2010-02-06 3 views
13

Мы хотели бы включить или отключить виджеты с помощью кода. Когда мы говорим, что «отключить» мы имеем в виду, что виджет, зарегистрированный в приложении , не должен отображаться в списке виджетов, доступных пользователю, когда они пытаются добавить виджет на свой домашний экран. Этот вопрос был задан, к сожалению, много раз без ответа .Динамическое включение или отключение виджета не работает

Был один ответ Диэнном 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 (находится в в Android-источнике Base.git в \ src \ base \ services \ java \ com \ android \ server), который загружает список доступных виджетов, кэширует этот список доступных виджетов. Если это так, то приведенный выше код , который включает или отключает компонент виджета, будет работать после сброса устройства , потому что кеша не будет; Это не.

Я также попытался переопределить некоторые методы приложения AppWidgetProvider, например, для фильтрации любых событий. Я не думаю, что это будет куда угодно, потому что AppWidgetService, который заполняет список , использует диспетчер пакетов, чтобы найти все компоненты, которые улавливают действие ACTION_APPWIDGET_UPDATE при запуске и когда добавлен пакет (т.е. новое приложение установлен). Единственный раз, когда провайдер удаляется из этого списка, является передача ACTION_PACKAGE_REMOVED. Так что, если провайдеры всегда будут там, независимо от состояния включения/отключения компонента, я просмотрел действительный список , который показан в приложении Launcher, когда пользователь long- нажимает рабочий стол и добавляет виджет: AppWidgetPickActivity в Settings.GIT в com.android.settings. Это, к сожалению, заполнит список непосредственно из AppWidgetService, без какой-либо фильтрации для статуса позволили компонента: недействительных putInstalledAppWidgets (Список элементов) { List установлен = mAppWidgetManager.getInstalledProviders(); putAppWidgetItems (установлено, null, items); }

Мне очень хотелось бы узнать, преодолел ли кто-либо этот барьер. Возможно, я ошибочно. Все, что я хочу, - это удалить виджет из списка виджетов, доступных пользователю, когда они попытаются установить , чтобы добавить виджет на главный экран.

+1

Любое обновление с этим вопросом после того, как 3-х лет? –

ответ

3

Может быть, что AppWidgetService (находится в Android Источника Base.git в \ SRC \ базы \ услуги \ Java \ COM \ андроида \ сервер), который загружает список доступных виджетов , кэширует этот список доступных виджетов.

Он делает, рядом, насколько я могу судить.Он хранит список в mInstalledProviders; этот список добавляется через readStateFromFileLocked(), который, как представляется, вызывается из логики запуска системы.

Если бы это было так, хотя, то приведенный выше код, который включает или выключает компонент виджет будет работы после сброса устройства, потому что не было бы никакого кэша; Это не.

Вы принимаете кеш оперативной памяти. Кэш - это XML-файл.

Это, к сожалению, заполнит список непосредственно из AppWidgetService, без фильтрации для компонента включен статус

И это казалось бы, ошибка в Android. В общем, вся кеширующая вещь, о которой я думаю, является ошибкой - я не вижу способа восстановить, если этот кеш выходит из синхронизации.

Я бы порекомендовал вам опубликовать вашу запись как проблему на public Android issue tracker, если вы еще этого не сделали.

1

Функция

pm.setComponentEnabledSetting() 

работает в ICS. Когда виджет отключен, он удаляется из списка доступных виджетов. Небольшое утешение на данный момент, но это по крайней мере исправлено.

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

Похоже, что включение/отключение работает только тогда, когда приемник в манифесте включен. Если он отключен манифестом, включение/отключение программно не работает. Пожалуйста, подтвердите это поведение? –

+0

@ peter.bartos Да, он работает только в том случае, если он первоначально включен в манифест. Также для приложения, чтобы отключить виджет, пользователю необходимо принудительно выйти из приложения, чтобы «обновить» список виджетов, если он не убивает его программно. – Cheruby

Смежные вопросы