Aktualisieren Sie das Widget programmgesteuert von Aktivität / Dienst / Empfänger


97

Ich weiß, dass es möglich ist, aber ich kann keine Möglichkeit finden, ein Update meines Widgets aus der Hauptaktivität auszulösen. Gibt es nicht eine allgemeine Absicht, die ich senden kann?

Antworten:


191

Wenn Sie sind ein verwenden AppWidgetProvider, können Sie es auf diese Weise aktualisieren:

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
Wo setzen Sie widgetId?
Kris B

38
@KrisB aus der Antwort unten, rufen Sie das Array folgendermaßen ab: int ids [] = AppWidgetManager.getInstance (getApplication ()). GetAppWidgetIds (neuer Komponentenname (getApplication (), WidgetProvider.class));
MobileMon

11
Sie können eine Konstante verwenden, ohne dass ein Hardcode erforderlich ist:intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
Mārtiņš Briedis

3
Folgen Sie NICHT dem Kommentar von @gelupa, um R.xml.mywidget für widgetID zu verwenden! Es ist VOLLSTÄNDIG falsch und hat mich nur 4 Stunden Debugging gekostet !!! Verwenden Sie MobileMon-Lösung, um die richtige Widget-ID zu erhalten
Ilja S.

5
für IDs: `int widgetIDs [] = AppWidgetManager.getInstance (Aktivität) .getAppWidgetIds (neuer Komponentenname (Aktivität, widget.class));`
abbasalim

75

Dies hat geholfen, als ich gesucht habe, wie ein Widget über einen Dienst oder eine Aktion aktualisiert werden kann (aber möglicherweise in jedem Kontext möglich ist):

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

Ich weiß, dass ich hier etwa 6 Monate zu spät einspringe. Aber ich stimme Andrew zu. Ich habe die ursprüngliche Methode in diesem Thread ausprobiert. Und etwas darüber, wie die IDs erfasst werden, führte dazu, dass sie fehlschlugen. Diese Methode (zum direkten manuellen Aktualisieren der Felder) funktioniert besser. Zumindest für meine Zwecke.
Durbnpoisn

Tolles Zeug. Ich weiß nicht, wie Sie dazu gekommen sind, aber es funktioniert gut und reibungslos für alle Instanzen meines Widgets. :)
Atul O Holic

das hat auch bei mir funktioniert. Ich dachte, wir müssten Broadcast und onReceive machen, aber meine Anforderungen passen perfekt dazu
stingray_

30

Um ein Widget aus einer Aktivität zu aktualisieren, können Sie dies folgendermaßen tun:

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

Funktioniert bei mir :)


Es ruft die onRecieve-Überschreibungsmethode auf. Aber ich möchte, wie man die onUpdate-Methode aufruft.
Amit Thaper

25

Versuche dies:

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

2
Erstaunlicherweise löste nur diese kleine Antwort das Problem. Ich weiß immer noch nicht, welche Auswirkungen es hat, die Widget-Klasse zu instanziieren und die onUpdate-Methode direkt aufzurufen, aber hey, es funktioniert endlich :)
Henrique de Sousa

1
Vielen Dank. Ich teste es jetzt und werde Feedback posten. Getestete und bestätigte Arbeit. Ich frage mich, ob es verschiedene Arten von Widgets gibt. Funktioniert es gleich? (+1 übrigens zum Arbeiten)
Si8

Ich bekomme immer IDs 0
Omor

Dies wird unter Android Oreo nicht funktionieren.
Stuckedoverflow

15

Wenn Sie mit einem Widget arbeiten, das eine Sammlung wie ListView, GridView oder StackView verwendet, um die Elemente des Widgets zu aktualisieren, gehen Sie wie folgt vor:

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

Mit dieser Methode notifyAppWidgetViewDataChanged () können Sie die Widget-Elemente zwingen, neue Daten in Echtzeit abzurufen.


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
Benötigt Min-API-Level: 11.
Anirudh Ramanathan

Genial. Sie müssen nicht einmal eine Schleife ausführen, es gibt eine Version notifyAppWidgetViewDataChanged(), die ein Array benötigt.
Lawrence Kesteloot

2

Phaethons akzeptierte Lösung in Kotlin:

    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)

Wo MyAppWidgetProvider von AppWidgetProvider abgeleitet ist:
class MyAppWidgetProvider : AppWidgetProvider() {


2

Wenn Sie versuchen, das Widget programmgesteuert zu aktualisieren, wenn Sie keinen expliziten Zugriff auf YourWidgetProvider.class haben, z. B. von einem anderen Modul oder einer anderen Bibliothek aus, können Sie die Ausgaben von YourWidgetProvider.class.getName () erfassen und eine Konstante erstellen:

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

Sie könnten dies dann implizit verwenden:

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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.