Динамическое включение или отключение виджета не работает
Мы хотели бы включить или отключить виджеты с помощью кода. Когда мы говорим
"disable" мы имеем в виду, что виджет, который зарегистрирован в приложении
не должны отображаться в списке виджетов, доступных пользователю, когда
они пытаются добавить виджет на свой домашний экран.
Этот вопрос задавался, к сожалению, много раз без
ответ.
Был один ответ Дайанн Хакборн на отдельный
вопрос о виджетах, в котором было предложено использовать
менеджер пакетов для отключения виджетов:
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 (расположенный
в Android-источнике Base.git в \src\base\services\java\com\android
\ server), который загружает список доступных виджетов, кэширует этот список
доступных виджетов. Если бы это было так, то вышеприведенное
код, который включает или отключает компонент виджетов, будет работать после
device reset, потому что не будет кеша; Это не.
Я также попытался пересмотреть некоторые методы
AppWidgetProvider, например, для фильтрации любых событий. Я не думаю
это пойдет куда угодно, потому что AppWidgetService, который заполняет
список, использует диспетчер пакетов, чтобы найти все компоненты, которые
действие ACTION_APPWIDGET_UPDATE при запуске и когда пакет
добавлено (т.е. установлено новое приложение). Единственный раз, когда поставщик
удаленный из этого списка, включен в эфир ACTION_PACKAGE_REMOVED.
Поэтому, учитывая, что поставщики всегда будут там, независимо от того,
включено/выключено состояние компонента, я просмотрел фактическое
который показан в приложении Launcher, когда пользователь долгое время,
нажимает на рабочий стол и добавляет виджет: AppWidgetPickActivity в
Настройки .GIT в
com.android.settings. Это, к сожалению, заполняет список
непосредственно из AppWidgetService, без какой-либо фильтрации для
статус компонента включен: void putInstalledAppWidgets (элементы списка) { Список установлен =
mAppWidgetManager.getInstalledProviders(); putAppWidgetItems (установлено, null, items); }
Мне бы хотелось увидеть, преодолел ли кто-нибудь это препятствие. Возможно, я
это происходит неправильно. Все, что я хочу, - это удалить
виджета из списка виджетов, доступных пользователю, когда они пытаются
добавьте виджет на главный экран.
Ответы
Ответ 1
Возможно, AppWidgetService (находится в Android-источнике Base.git at \ SRC\база\услуги\Java\COM\андроида \ server), который загружает список доступных виджетов, кэширует этот список доступных виджетов.
Он делает, рядом, насколько я могу судить. Он хранит список в mInstalledProviders
; этот список добавляется через readStateFromFileLocked()
, который, как представляется, вызывается из логики запуска системы.
Если бы это было так, то приведенный выше код, который позволяет или отключает компонент виджета работать после устройства reset, потому что не было бы кеша; это не так.
Вы принимаете кеш RAM. Кэш - это XML файл.
Это, к сожалению, заполняет перечислить непосредственно из AppWidgetService, без каких-либо фильтрация для включенного компонента статус
И это будет ошибкой в Android. В общем, вся кеширующая вещь, о которой я думаю, является ошибкой - я не вижу способа восстановить, если этот кеш выходит из синхронизации.
Я бы порекомендовал вам опубликовать вашу запись в качестве проблемы в общедоступном трекере для Android, если вы этого еще не сделали.
Ответ 2
Это сработало для меня! Мне пришлось использовать 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 + " )..." );
}
Ответ 3
Функция
pm.setComponentEnabledSetting()
работает в ICS. Когда виджет отключен, он удаляется из списка доступных виджетов. Небольшое утешение на данный момент, но оно по крайней мере было исправлено.