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.