Mettre à jour le widget par programme depuis l'activité / le service / le récepteur


97

Je sais que c'est possible, mais je n'arrive pas à trouver un moyen de déclencher une mise à jour de mon widget à partir de l'activité principale. N'y a-t-il pas une intention générale que je puisse diffuser?

Réponses:


191

Si vous êtes utilisez un AppWidgetProvider, vous pouvez le mettre à jour la façon suivante :

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
Où vous placez-vous widgetId?
Kris B

38
@KrisB à partir de la réponse ci-dessous, obtenez le tableau en faisant ceci: int ids [] = AppWidgetManager.getInstance (getApplication ()). GetAppWidgetIds (new ComponentName (getApplication (), WidgetProvider.class));
MobileMon

11
Vous pouvez utiliser une constante, pas besoin de coder en dur:intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
Mārtiņš Briedis

3
NE PAS suivre le commentaire @gelupa pour utiliser R.xml.mywidget pour widgetID! C'est TOTALEMENT faux et cela m'a coûté 4 heures de débogage !!! Utilisez la solution MobileMon pour obtenir le widgetID correct
Ilja S.

5
pour les ids: `int widgetIDs [] = AppWidgetManager.getInstance (activité) .getAppWidgetIds (new ComponentName (activity, widget.class));`
abbasalim

75

Cela m'a aidé lorsque j'ai cherché comment mettre à jour un widget à partir d'un service / ou d'une action (mais cela peut être possible dans tous les contextes):

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

Je sais que je saute ici avec 6 mois de retard. Mais je suis d'accord avec Andrew. J'ai essayé la méthode originale dans ce fil. Et quelque chose à propos de la façon dont les identifiants sont saisis a provoqué un échec. Cette méthode (de mise à jour directe des champs manuellement) fonctionne mieux. Pour mes besoins, au moins.
durbnpoisn

Des trucs géniaux. Je ne sais pas comment vous vous êtes retrouvé avec cela, mais fonctionne très bien pour toutes les instances de mon widget. :)
Atul O Holic

cela a fonctionné pour moi aussi. Je pensais que nous aurions besoin de diffuser et de recevoir en ligne, mais mes exigences correspondent parfaitement à cela
stingray_

30

Donc, pour mettre à jour un widget à partir d'une activité, vous pouvez le faire comme ceci:

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

Travaille pour moi :)


Il appelle la méthode de substitution onRecieve. Mais je veux comment appeler la méthode onUpdate.
Amit Thaper

25

Essaye ça:

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

2
Étonnamment, seule cette petite réponse l'a résolu. Je ne connais toujours pas les implications de l'instanciation de la classe Widget et de l'appel direct de la méthode onUpdate, mais bon, ça marche enfin :)
Henrique de Sousa

1
Merci. Je le teste maintenant et publierai des commentaires. Fonctionnement testé et confirmé. Je me demande si il existe différents types de widgets, cela fonctionnera-t-il de la même manière? (+1 au fait pour travailler)
Si8

je reçois toujours des identifiants 0
omor

Cela ne fonctionnera pas sur Android Oreo, aucune solution de contournement?
stuckedoverflow

15

Si vous travaillez avec un widget qui utilise une collection telle que ListView, GridView ou StackView, pour mettre à jour les éléments du widget, procédez comme suit:

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

Avec cette méthode notifyAppWidgetViewDataChanged (), vous pouvez forcer les éléments du widget à récupérer toutes les nouvelles données en temps réel.


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
Nécessite le niveau min-api: 11.
Anirudh Ramanathan

Impressionnant. Vous n'avez même pas besoin de boucler, il existe une version de notifyAppWidgetViewDataChanged()cela prend un tableau.
Lawrence Kesteloot

2

La solution acceptée de Phaethon à 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)

Où MyAppWidgetProvider est dérivé de AppWidgetProvider:
class MyAppWidgetProvider : AppWidgetProvider() {


2

Si vous essayez de mettre à jour par programme le widget où vous n'avez pas accès à YourWidgetProvider.class explicitement, par exemple à partir d'un autre module ou d'une autre bibliothèque, vous pouvez capturer ce que YourWidgetProvider.class.getName () produit et créer une constante:

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

Vous pourrez alors l'utiliser implicitement:

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)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.