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?

Nuvious
quelle

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);
Phaethon
quelle
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);
Stecken
quelle
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 :)

Voidcode
quelle
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);
Oleg Tarashkevich
quelle
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.

alshtd
quelle
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
quelle
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() {

Elletlar
quelle
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)
Gareoke
quelle