Programowo aktualizuj widżet z aktywności / usługi / odbiorcy


97

Wiem, że to możliwe, ale nie mogę znaleźć sposobu, aby wywołać aktualizację mojego widżetu z głównego działania. Czy nie ma jakichś ogólnych zamiarów, które mogę przekazać?

Odpowiedzi:


191

Jeśli stosując AppWidgetProvidermożna zaktualizować to w ten sposób:

Intent intent = new Intent(this, MyAppWidgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
// Use an array and EXTRA_APPWIDGET_IDS instead of AppWidgetManager.EXTRA_APPWIDGET_ID,
// since it seems the onUpdate() is only fired on that:
 int[] ids = AppWidgetManager.getInstance(getApplication())
    .getAppWidgetI‌​ds(new ComponentName(getApplication(), MyAppWidgetProvider.class));
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
sendBroadcast(intent);

30
Gdzie ustawiasz widgetId?
Kris B

38
@KrisB z odpowiedzi poniżej, pobierz tablicę, wykonując następujące czynności: int ids [] = AppWidgetManager.getInstance (getApplication ()). GetAppWidgetIds (new ComponentName (getApplication (), WidgetProvider.class));
MobileMon

11
Możesz użyć stałej, bez potrzeby kodowania na stałe:intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
Mārtiņš Briedis

3
NIE śledź komentarza @gelupa, aby używać R.xml.mywidget dla widgetID! Jest to ZUPEŁNIE błędne i kosztuje mnie tylko 4 godziny debugowania !!! UŻYJ rozwiązania MobileMon, aby uzyskać poprawny identyfikator widżetu
Ilja S.,

5
dla identyfikatorów: `int widgetIDs [] = AppWidgetManager.getInstance (aktywność) .getAppWidgetIds (new ComponentName (activity, widget.class));`
abbasalim

75

Pomogło to, gdy szukałem, jak zaktualizować widżet z usługi / lub akcji (ale może to być możliwe z każdego kontekstu):

Context context = this;
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_2x1);
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
remoteViews.setTextViewText(R.id.my_text_view, "myText" + System.currentTimeMillis());
appWidgetManager.updateAppWidget(thisWidget, remoteViews);

Wiem, że skaczę tu z 6-miesięcznym opóźnieniem. Ale zgadzam się z Andrew. Wypróbowałem oryginalną metodę w tym wątku. A coś w tym, jak przechwytywane są identyfikatory, spowodowało, że zaczęło się to nie udawać. Ta metoda (bezpośredniego ręcznego aktualizowania pól) działa lepiej. Przynajmniej dla moich celów.
durbnpoisn

Niesamowite rzeczy. Nie wiem, jak to się stało, ale działa dobrze i płynnie dla wszystkich wystąpień mojego Widżetu. :)
Atul O Holic

to też działało dla mnie. Myślałem, że będziemy musieli nadawać i odbierać, ale moje wymagania idealnie do tego pasują
stingray_

30

Aby zaktualizować widżet z działania, możesz to zrobić w następujący sposób:

Intent intent = new Intent(this, DppWidget.class);
intent.setAction("android.appwidget.action.APPWIDGET_UPDATE");
int ids[] = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), DppWidget.class));
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,ids);
sendBroadcast(intent);

Pracuje dla mnie :)


Wywołuje metodę przesłonięcia onRecieve. Ale chcę, jak wywołać metodę onUpdate.
Amit Thaper

25

Spróbuj tego:

int[] ids = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), MyWidget.class));
        MyWidget myWidget = new MyWidget();
        myWidget.onUpdate(this, AppWidgetManager.getInstance(this),ids);

2
O dziwo, tylko ta mała odpowiedź rozwiązała problem. Nadal nie znam konsekwencji tworzenia instancji klasy Widget i bezpośredniego wywoływania metody onUpdate, ale hej, w końcu działa :)
Henrique de Sousa

1
Dzięki. Testuję to teraz i opublikuję opinię. Sprawdzone i potwierdzone działanie. Zastanawiam się, czy jeśli istnieją różne rodzaje widżetów, czy będzie działać tak samo? (Przy okazji +1 za pracę)
Si8

Zawsze otrzymuję identyfikatory 0
omor

To nie zadziała na Androidzie Oreo, jakakolwiek naprawa obejścia?
stuckedoverflow

15

Jeśli pracujesz z widżetem, który używa kolekcji, takiej jak ListView, GridView lub StackView, aby zaktualizować elementy widżetu, wykonaj następujące czynności:

Context context = getApplicationContext();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisWidget = new ComponentName(context, StackWidgetProvider.class);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.stack_view);

Za pomocą tej metody notifyAppWidgetViewDataChanged () można wymusić na elementach widgetu pobieranie nowych danych w czasie rzeczywistym.


12
int widgetIDs[] = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), WidgetProvider.class));

for (int id : widgetIDs)
    AppWidgetManager.getInstance(getApplication()).notifyAppWidgetViewDataChanged(id, R.id.widget_view);
}

1
Wymaga poziomu min-api: 11.
Anirudh Ramanathan

Niesamowite. Nie musisz nawet zapętlać, istnieje wersja, notifyAppWidgetViewDataChanged()która pobiera tablicę.
Lawrence Kesteloot

2

Zaakceptowane rozwiązanie Phaethona w Kotlinie:

    val intent = Intent(this, MyAppWidgetProvider::class.java)
    intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
    val ids = AppWidgetManager.getInstance(application).getAppWidgetIds(ComponentName(getApplicationContext(),MyAppWidgetProvider::class.java!!))
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
    sendBroadcast(intent)

Gdzie MyAppWidgetProvider pochodzi od AppWidgetProvider:
class MyAppWidgetProvider : AppWidgetProvider() {


2

Jeśli próbujesz programowo zaktualizować widżet, w którym nie masz jawnie dostępu do YourWidgetProvider.class, np. Z innego modułu lub biblioteki, możesz przechwycić dane wyjściowe YourWidgetProvider.class.getName () i utworzyć stałą:

val WIDGET_CLASS_NAME = "com.example.yourapplication.YourWidgetProvider"

Byłbyś wtedy w stanie użyć tego niejawnie:

val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE)
val widgetManager = AppWidgetManager.getInstance(context)
val ids = widgetManager.getAppWidgetIds(ComponentName(context, WIDGET_CLASS_NAME))
AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(ids, android.R.id.list)
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
context.sendBroadcast(intent)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.