Программное обновление виджета из активности / сервиса / получателя

97

Я знаю, что это возможно, но не могу понять, как запустить обновление моего виджета из основного действия. Разве я не могу транслировать какое-то общее намерение?

Nuvious
источник

Ответы:

192

Если будут используя AppWidgetProvider, вы можете обновить его таким образом:

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
Где ты сидишь widgetId?
Kris B
38
@KrisB из ответа ниже, получите массив следующим образом: int ids [] = AppWidgetManager.getInstance (getApplication ()). GetAppWidgetIds (new ComponentName (getApplication (), WidgetProvider.class));
MobileMon
11
Вы можете использовать константу, жестко кодировать не нужно:intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
Мартиньш Бриедис
3
НЕ подписывайтесь на комментарий @gelupa, чтобы использовать R.xml.mywidget для widgetID! Это ПОЛНОСТЬЮ неверно и стоило мне 4 часов отладки !!! ИСПОЛЬЗУЙТЕ решение MobileMon, чтобы получить правильный идентификатор виджета
Илья С.
5
для идентификаторов: `int widgetIDs [] = AppWidgetManager.getInstance (activity) .getAppWidgetIds (new ComponentName (activity, widget.class));`
abbasalim
76

Это помогло, когда я искал, как обновить виджет из службы / или действия (но может быть возможно из любого контекста):

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);
Застрял
источник
Я знаю, что прыгаю сюда с опозданием на 6 месяцев. Но я согласен с Андреем. Я пробовал оригинальный метод в этой ветке. И что-то в том, как захватываются идентификаторы, заставило его начать отказывать. Этот метод (прямого обновления полей вручную) работает лучше. По крайней мере, для моих целей.
durbnpoisn
Классный материал. Не знаю, как вы к этому пришли, но работает нормально и плавно для всех экземпляров моего виджета. :)
Атул О Холич
это сработало и для меня. Я думал, что нам нужно будет сделать трансляцию и onReceive, но мои требования идеально подходят для этого
stingray_
30

Итак, чтобы обновить виджет из активности, вы можете сделать это следующим образом:

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

Работает для меня :)

Voidcode
источник
Он вызывает метод переопределения onRecieve. Но я хочу, как вызвать метод onUpdate.
Амит Тапер,
25

Попробуй это:

int[] ids = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), MyWidget.class));
        MyWidget myWidget = new MyWidget();
        myWidget.onUpdate(this, AppWidgetManager.getInstance(this),ids);
Олег Тарашкевич
источник
2
Удивительно, но только этот небольшой ответ решил ее. Я до сих пор не знаю последствий создания экземпляра класса Widget и прямого вызова метода onUpdate, но, эй, он наконец-то работает :)
Энрике де Соуза,
1
Спасибо. Сейчас я тестирую его и оставлю отзыв. Протестировано и подтверждено, что работает. Мне интересно, если есть разные типы виджетов, они будут работать одинаково? (+1 кстати за рабочий)
Si8
я всегда получаю идентификаторы 0
omor
Это не будет работать на Android Oreo. Какое решение?
stuckedoverflow
15

Если вы работаете с виджетом, который использует такую ​​коллекцию, как ListView, GridView или StackView, для обновления элементов виджета, сделайте следующее:

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

С помощью этого метода notifyAppWidgetViewDataChanged () вы можете заставить элементы виджета получать любые новые данные в реальном времени.

thanhtd
источник
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
Требуется уровень мин-апи: 11.
Анируд Раманатан 07
Потрясающие. Вам даже не нужно зацикливаться, есть версия, notifyAppWidgetViewDataChanged()которая принимает массив.
Лоуренс Кестелут
2

Принятое решение Фаэтона в Котлине:

    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)

Где MyAppWidgetProvider является производным от AppWidgetProvider:
class MyAppWidgetProvider : AppWidgetProvider() {

Elletlar
источник
2

Если вы пытаетесь программно обновить виджет, в котором у вас нет доступа к YourWidgetProvider.class явно, например, из другого модуля или библиотеки, вы можете записать, что выводит YourWidgetProvider.class.getName (), и создать константу:

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

Тогда вы сможете использовать это неявно:

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)
Гароке
источник