Atualizar programaticamente o widget de atividade / serviço / receptor


97

Eu sei que é possível, mas não consigo descobrir uma maneira de acionar uma atualização do meu widget a partir da atividade principal. Não existe alguma intenção geral que eu possa transmitir?

Respostas:


191

Se você estiver usando um AppWidgetProvider, poderá atualizá-lo desta forma:

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
Onde você define widgetId?
Kris B

38
@KrisB pela resposta abaixo, obtenha o array fazendo o seguinte: int ids [] = AppWidgetManager.getInstance (getApplication ()). GetAppWidgetIds (new ComponentName (getApplication (), WidgetProvider.class));
MobileMon

11
Você pode usar uma constante, sem necessidade de codificar:intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
Mārtiņš Briedis

3
NÃO siga o comentário de @gelupa para usar R.xml.mywidget para widgetID! É COMPLETAMENTE errado e só me custou 4 horas de depuração !!! USE a solução MobileMon para obter o widgetID correto
Ilja S.

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

75

Isso ajudou quando eu pesquisei sobre como atualizar um widget de um serviço / ou ação (mas pode ser possível em todos os 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);

Eu sei que estou entrando aqui com 6 meses de atraso. Mas concordo com Andrew. Tentei o método original neste tópico. E algo sobre como os IDs são capturados fez com que ele começasse a falhar. Este método (de atualização direta dos campos manualmente) funciona melhor. Para meus propósitos, pelo menos.
durbnpoisn

Coisas incríveis. Não sei como você terminou com isso, mas funciona bem e sem problemas para todas as instâncias do meu Widget. :)
Atul O Holic

isso funcionou para mim também. Achei que precisaríamos fazer broadcast e onReceive, mas meus requisitos se encaixam perfeitamente com isso
stingray_

30

Então, para atualizar um widget de uma atividade, você pode fazer assim:

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 mim :)


Ele chama o método de substituição onRecieve. Mas eu quero como chamar o método onUpdate.
Amit Thaper de

25

Experimente isto:

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

2
Surpreendentemente, apenas esta pequena resposta o resolveu. Ainda não sei as implicações de instanciar a classe Widget e chamar diretamente o método onUpdate, mas ei, finalmente funciona :)
Henrique de Sousa

1
Obrigado. Estou testando agora e postarei feedback. Testado e confirmado em funcionamento. Eu estou pensando, se houver diferentes tipos de widgets, eles funcionarão da mesma forma? (A propósito, +1 para trabalhar)
Si8

Eu sempre recebo ids 0
ou

Isso não funcionará no Android Oreo. Alguma solução alternativa?
stickedoverflow

15

Caso você esteja trabalhando com um widget que usa uma coleção como ListView, GridView ou StackView, para atualizar os itens do widget, faça o seguinte:

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

Com este método NoticeAppWidgetViewDataChanged (), você pode forçar os itens do widget a buscar quaisquer novos dados em tempo real.


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
Requer nível min-api: 11.
Anirudh Ramanathan

Impressionante. Você nem mesmo precisa fazer um loop, há uma versão notifyAppWidgetViewDataChanged()que leva um array.
Lawrence Kesteloot

2

Solução aceita de Phaethon em 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)

Onde MyAppWidgetProvider é derivado de AppWidgetProvider:
class MyAppWidgetProvider : AppWidgetProvider() {


2

Se você estiver tentando atualizar programaticamente o widget onde não tem acesso a YourWidgetProvider.class explicitamente, por exemplo, de outro módulo ou biblioteca, você pode capturar o que YourWidgetProvider.class.getName () produz e criar uma constante:

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

Você poderia então usar isso implicitamente:

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)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.