动态启用或禁用小部件不起作用
我们希望通过代码启用或禁用小部件。 当我们说“禁用”时,我们的意思是在应用程序中注册的小部件不应该显示在用户可用的小部件列表中,当他们尝试将小部件添加到其主屏幕时。 不幸的是,这个问题多次被问及没有答案。
Dianne Hackborn回应了一个单独的小部件问题,这表明可以使用包管理器来禁用小部件:
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(new ComponentName("com.example.android.apis", ".appwidget.ExampleBroadcastReceiver"),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, // or DISABLED
PackageManager.DONT_KILL_APP);
但是,这不起作用。 小部件组件仍将出现在小部件列表中。 可能是加载可用小部件列表的AppWidgetService(位于 src base services java com android server的Android源代码的Base.git中)缓存此可用小部件的列表。 但是,如果是这种情况,那么启用或禁用小部件组件的上述代码将在设备重置后工作,因为不会有缓存; 它不是。
我也尝试过重写AppWidgetProvider的一些方法,比如过滤掉任何事件。 我认为这不会发生在任何地方,因为填充列表的AppWidgetService使用包管理器来查找在启动时以及添加包(即安装了新应用程序)时捕获ACTION_APPWIDGET_UPDATE操作的所有组件。 从此列表中删除提供程序的唯一时间是ACTION_PACKAGE_REMOVED广播。 因此,无论组件的启用/禁用状态如何,我一直在研究从Launcher应用程序中显示的实际列表活动,当用户长时间点击桌面并添加一个窗口小部件时:AppWidgetPickActivity在com.android.settings中的Settings.GIT中。 不幸的是,它直接从AppWidgetService填充列表,没有对组件的启用状态进行任何筛选:void putInstalledAppWidgets(List items){List installed = mAppWidgetManager.getInstalledProviders(); putAppWidgetItems(已安装,null,项目); }
我很想看看有没有人克服了这个障碍。 也许我正在以错误的方式去做。 我想要的只是能够在用户尝试向其主屏幕添加小部件时从用户可用的小部件列表中移除小部件。
可能是加载可用小部件列表的AppWidgetService(位于 src base services java com android server的Android源代码的Base.git中)缓存此可用小部件的列表。
它的确如我所知的那样。 它将列表存储在mInstalledProviders
; 这个列表通过readStateFromFileLocked()
添加,它似乎是从系统启动逻辑中调用的。
但是,如果是这种情况,那么启用或禁用小部件组件的上述代码将在设备重置后工作,因为不会有缓存; 它不是。
你假设一个RAM缓存。 缓存是一个XML文件。
不幸的是,这直接从AppWidgetService填充列表,没有对组件启用状态进行过滤
这似乎是Android中的一个错误。 更一般地说,我认为整个缓存是bug - 如果缓存不同步,我无法恢复。
如果您尚未这样做,我会建议您在公开的Android问题跟踪器上发布您的文章作为问题。
它为我工作! 我不得不使用DONT_KILL_APP,否则它会立即杀死我的应用程序。 另外,我必须评论条件,以检查它是否已经处于相同的状态。
这是我创建的帮助器方法:
public void setMyCustomWidgetEnabled( boolean bEnable )
{
Log.d( LOG_TAG_NAME, "Entering setMyCustomWidgetEnabled( " + bEnable + " )..." );
PackageManager rPackageManager = getPackageManager();
if( rPackageManager != null )
{
ComponentName rComponentName = new ComponentName( getBaseContext(), MyCustomWidget.class );
int nComponentEnabledState = rPackageManager.getComponentEnabledSetting( rComponentName );
if( bEnable )
{
//if( nComponentEnabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED )
{
// Change the State to Enabled
rPackageManager.setComponentEnabledSetting( rComponentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP );
Log.d( LOG_TAG_NAME, "-> Changed My Custom Widget' to ENABLED!" );
}
}
else
{
//if( nComponentEnabledState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED )
{
// Change the State to Disabled
rPackageManager.setComponentEnabledSetting( rComponentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP );
Log.d( LOG_TAG_NAME, "-> Changed 'My Custom Widget' to DISABLED!" );
}
}
}
Log.d( LOG_TAG_NAME, "Leaving setMyCustomWidgetEnabled( " + bEnable + " )..." );
}
该功能
pm.setComponentEnabledSetting()
在ICS工作。 当小部件被禁用时,它将从可用小部件列表中删除。 目前小小的安慰,但它至少已被纠正。
链接地址: http://www.djcxy.com/p/8927.html上一篇: Dynamically enabling or disabling a widget does not work