Actualizar el widget de forma programática desde la actividad / servicio / receptor

97

Sé que es posible, pero no puedo encontrar la manera de activar una actualización de mi widget desde la actividad principal. ¿No hay alguna intención general que pueda transmitir?

Nuvious
fuente

Respuestas:

191

Si está utilizando un AppWidgetProvider, puede actualizarlo de esta manera:

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);
faetón
fuente
30
¿Dónde te pones widgetId?
Kris B
38
@KrisB de la respuesta a continuación, obtenga la matriz haciendo esto: int ids [] = AppWidgetManager.getInstance (getApplication ()). GetAppWidgetIds (new ComponentName (getApplication (), WidgetProvider.class));
MobileLun
11
Puede usar una constante, sin necesidad de codificar:intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
Mārtiņš Briedis
3
¡NO siga el comentario de @gelupa para usar R.xml.mywidget para widgetID! ¡Es COMPLETAMENTE incorrecto y solo me costó 4 horas de depuración! USE la solución MobileMon para obtener el widgetID correcto
Ilja S.
5
para ids: `int widgetIDs [] = AppWidgetManager.getInstance (actividad) .getAppWidgetIds (nuevo ComponentName (actividad, widget.class));`
abbasalim
75

Esto ayudó cuando busqué cómo actualizar un widget desde un servicio / acción (pero puede ser posible desde todos los contextos):

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);
Atascado
fuente
Sé que estoy saltando aquí como 6 meses tarde. Pero estoy de acuerdo con Andrew. Probé el método original en este hilo. Y algo sobre cómo se toman las identificaciones hizo que comenzara a fallar. Este método (de actualizar directamente los campos manualmente) funciona mejor. Para mis propósitos, al menos.
durbnpoisn
Cosas geniales. No sé cómo terminó con esto, pero funciona bien y sin problemas para todas las instancias de mi Widget. :)
Atul O Holic
Esto funcionó para mí también. Pensé que tendríamos que hacer la transmisión y el onReceive, pero mis requisitos encajan perfectamente con esto
stingray_
30

Entonces, para actualizar un widget a partir de una actividad, puede hacerlo así:

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

Funciona para mi :)

Voidcode
fuente
Llama al método de invalidación onRecieve. Pero quiero cómo llamar al método onUpdate.
Amit Thaper
25

Prueba esto:

int[] ids = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), MyWidget.class));
        MyWidget myWidget = new MyWidget();
        myWidget.onUpdate(this, AppWidgetManager.getInstance(this),ids);
Oleg Tarashkevich
fuente
2
Sorprendentemente, solo esta pequeña respuesta lo resolvió. Todavía no conozco las implicaciones de crear una instancia de la clase Widget y llamar directamente al método onUpdate, pero bueno, finalmente funciona :)
Henrique de Sousa
1
Gracias. Lo estoy probando ahora y publicaré comentarios. Trabajo probado y confirmado. Me pregunto si hay diferentes tipos de widgets, ¿funcionarán igual? (+1 por cierto para trabajar)
Si8
obtengo siempre ids 0
omor
Esto no funcionará en Android Oreo, ¿alguna solución alternativa?
stuckedoverflow
15

En caso de que esté trabajando con un widget que usa una colección como ListView, GridView o StackView, para actualizar los elementos del widget, haga lo siguiente:

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

Con este método notifyAppWidgetViewDataChanged (), puede forzar a los elementos del widget a buscar nuevos datos en tiempo real.

gracias
fuente
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
fuente
1
Requiere nivel min-api: 11.
Anirudh Ramanathan
Increíble. Ni siquiera tienes que hacer un bucle, hay una versión de notifyAppWidgetViewDataChanged()eso que requiere una matriz.
Lawrence Kesteloot
2

Solución aceptada de Phaethon en 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)

Donde MyAppWidgetProvider se deriva de AppWidgetProvider:
class MyAppWidgetProvider : AppWidgetProvider() {

Elletlar
fuente
2

Si está intentando actualizar mediante programación el widget donde no tiene acceso a YourWidgetProvider.class explícitamente, por ejemplo, desde otro módulo o biblioteca, puede capturar lo que YourWidgetProvider.class.getName () genera y crear una constante:

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

Entonces podrás usar esto implícitamente:

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
fuente