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ć?

Nuvious
źródło

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);
Phaethon
źródło
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);
Oblepiony
źródło
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 :)

Voidcode
źródło
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);
Oleg Tarashkevich
źródło
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.

thanhtd
źródło
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);
}
Jakob Eriksson
źródło
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() {

Elletlar
źródło
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)
gareoke
źródło