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?

Nuvieux
la source

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);
phaéton
la source
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);
Coincé
la source
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 :)

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

thanhtd
la source
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
la source
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() {

Elletlar
la source
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)
gareoke
la source