setComponentEnabledSetting doesn't work on widget 以及副作用

PackageManager.setComponentEnabledSetting 可以用来禁用某个组件,包括activity,receiver等等。被禁用的组件会被持久化到/data/system/packages.xml中,如:

<package name="com.android.setupwizard" codePath="/system/app/SetupWizard.apk" nativeLibraryPath="/data/data/com.android.setupwizard/lib" flags="1" ft="13349457a90" it="13349457a90" ut="13349457a90" version="130" userId="10016">
<sigs count="1">
<cert index="0" />
</sigs>
<disabled-components>
<item name="com.android.setupwizard.SetupWizardActivity" />
</disabled-components>
</package>

现在需要在运行时禁用某个widget,同时有一个system property用来标识是否需要禁用。
因为widget实际上就是个reveiver,它接收android.appwidget.action.APPWIDGET_UPDATE的action,所以开始的思路是:
创建一个BroadcastReceiver,接收Intent.ACTION_BOOT_COMPLETED这个动作,从而在启动完成后调用SystemProperties.get("disable_widget"),如果需要禁用这个widget,那么调用:
PackageManager.setComponentEnabledSetting(widgetComponentName,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);

但是问题是,调用这个方法disable掉这个widget后,发现必须把设备重启之后才能生效...
经过google,发现问题出在com.android.server.AppWidgetService.java。
原来开机后,SystemServer会调用AppWidgetService的systemReady()方法,这个方法通过PackageManager查询所有的widget receiver组件,保存到mInstalledProviders变量列表中,并持久化widget信息到/data/system/appwidgets.xml中。
而在Launcher上长按添加widget时的那个widget列表信息也是通过AppWidgetService取得mInstalledProviders列表。
问题在于我们通过PackageManager.setComponentEnabledSetting()禁用掉某个widget后,packagemanager确实将这个组件disable了,但是AppWidgetService却没有去从packagemanager reload widget信息,这就导致了mInstalledProviders中保存的widget信息还是开机时load进来的那些信息,并没有与pm进行同步。直到下一次开机调用systemReady重新加载widget信息才会刷新这个列表。

参考:
Dynamically enabling or disabling a widget with PackageManager.setComponentEnabledSetting does not work
http://code.google.com/p/android/issues/detail?id=6533

http://blog.csdn.net/vincent_czz/article/details/7278801

-------------------------------------------------------------------

PackageManager.setComponentEnabledSetting函数可以把某个ComponentName的state设为false或true,

Android中对于state为false的Activity,是不能onCreate,如果该Activity对应与某个APK的Main Activity,则该APK在state为false时,其相应的图标不会显示在可启动程序列表里,即不能通过Main Launcher Intent filter query出来。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值