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?

Nuvious
fonte

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);
faethon
fonte
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);
Preso
fonte
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 :)

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

Thanhtd
fonte
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
fonte
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() {

Elletlar
fonte
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)
gareoke
fonte