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 są 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.