2010-02-06 16 views
13

Chcielibyśmy włączyć lub wyłączyć widżety za pomocą kodu. Kiedy mówimy "wyłącz", oznacza to, że widżet zarejestrowany w aplikacji nie powinien się pojawiać na liście widżetów dostępnych dla użytkownika, gdy próbuje on dodać widżet do ich ekranu głównego. To pytanie zostało zadane, niestety, wiele razy bez odpowiedzi .Dynamiczne włączanie lub wyłączanie widżetu nie działa

Była jedna odpowiedź przez Dianne Hackborn do oddzielnego widget pytanie, który sugerował, że można było użyć menedżera pakietów wyłączyć widżety:

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); 

To jednak nie działa. Element widget nadal będzie wyglądał na liście widgetów na . Być może AppWidgetService (znajduje się w źródle bazowym Androida na serwerze \ src \ base \ services \ java \ com \ android \ server), które ładuje listę dostępnych widżetów, buforuje tę listę dostępnych widżetów. Jeśli tak było, to powyższy kod , który włącza lub wyłącza komponent widgetu, działałby po zresetowaniu urządzenia , ponieważ nie byłoby pamięci podręcznej; to nie.

Próbowałem również sprawdzić nadpisanie niektórych metod AppWidgetProvider, takich jak filtrowanie wszelkich zdarzeń. Nie sądzę, to pójdzie w dowolnym miejscu, ponieważ AppWidgetService, która zapełnia listę, używa Menedżera pakietów, aby znaleźć wszystkie składniki, które złapie akcji ACTION_APPWIDGET_UPDATE podczas uruchamiania i gdy pakiet jest dodane (tj. Nowa aplikacja jest zainstalowany). Jedyny przypadek usunięcia z tej listy operatora dotyczy transmisji ACTION_PACKAGE_REMOVED. Biorąc pod uwagę, że dostawcy zawsze będą tam obecni, niezależnie od stanu włączonego/wyłączonego komponentu , przejrzałem rzeczywistą aktywność listy, która jest wyświetlana z aplikacji Launcher, gdy użytkownik długo- klika pulpit i dodaje widget: AppWidgetPickActivity w Ustawienia.GIT w com.android.settings. To, niestety, zapełnia listę bezpośrednio z AppWidgetService bez filtrowania dla statusu umożliwiło komponentu: void putInstalledAppWidgets (elementy listy) { liście Zainstalowane = mAppWidgetManager.getInstalledProviders(); putAppWidgetItems (zainstalowane, puste, elementy); }

Chciałbym zobaczyć, czy ktoś pokonał tę przeszkodę. Być może jestem dzieje się w niewłaściwy sposób. Wszystko czego chcę, to móc usunąć widget z listy widżetów dostępnych dla użytkownika, gdy próbuje on dodać widżet do ich ekranu głównego.

+1

Każda aktualizacja tej kwestii po 3 latach? –

Odpowiedz

3

może być tak, że AppWidgetService (znajduje się w Android źródłowego Base.git na \ Services src \ base \ \ Java \ com \ android \ server), który ładuje listę dostępnych widżetów , buforuje tę listę dostępnych widżetów w postaci .

Jest tak blisko, jak mogę powiedzieć.Przechowuje listę w mInstalledProviders; ta lista jest dodawana do poprzez readStateFromFileLocked(), która wydaje się być wywoływana z logiki uruchamiania systemu.

Jeśli tak było, choć wtedy powyższy kod, który włącza lub wyłącza składnik widget będzie praca po resecie urządzenia, ponieważ nie byłoby żadnego cache; to nie.

Zakładasz pamięć podręczną RAM. Pamięć podręczna jest plikiem XML.

To, niestety, zapełnia listę bezpośrednio z AppWidgetService bez filtrowania dla komponentu pozwoliło statusu

I to wydaje się być błąd w Androidzie. Bardziej ogólnie rzecz biorąc, cała sprawa z buforowaniem, którą uważam za błąd, nie jest w stanie odzyskać, jeśli pamięć podręczna nie będzie zsynchronizowana.

Zalecam, aby opublikować swój zapis jako problem na public Android issue tracker, jeśli jeszcze tego nie zrobiłeś.

1

Funkcja

pm.setComponentEnabledSetting() 

prace w ICS. Gdy widget jest wyłączony, zostaje usunięty z listy dostępnych widżetów. Mała pociecha w tej chwili, ale przynajmniej została poprawiona.

2

To zadziałało dla mnie! Musiałem użyć DONT_KILL_APP lub natychmiast zabiłbym moją aplikację. Musiałem również skomentować warunek, aby sprawdzić, czy był już w tym samym stanie.

Oto metoda pomocnika stworzyłem:

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

Wygląda na to, że włączenie/wyłączenie działa tylko wtedy, gdy odbiornik w manifeście jest pierwotnie włączony. Jeśli jest wyłączone przez manifest, włączanie/wyłączanie programowo nie działa. Czy możesz potwierdzić to zachowanie? –

+0

@ peter.bartos Tak, działa tylko wtedy, gdy jest włączony w manifeście. Również dla aplikacji, aby wyłączyć widget, użytkownik musi wymusić zamknięcie aplikacji, aby "zaktualizować" listę widżetów, jeśli nie zabije go programowo. – Cheruby

Powiązane problemy