从活动/服务/接收者以编程方式更新小部件


97

我知道这是可能的,但我想不出一种从主要活动中触发小部件更新的方法。我没有可以广播的一般意图吗?

Answers:


191

如果您正在使用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 2012年

11
您可以使用恒定的,没有必要硬编码:intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
马丁斯Briedis

3
不要按照@gelupa注释将R.xml.mywidget用于widgetID!这是完全错误的,只花了我4个小时的调试时间!!!使用MobileMon解决方案获取正确的widgetID
Ilja S.

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

75

当我搜索如何从服务/或操作中更新窗口小部件时这很有帮助(但可能在每个上下文中都可以):

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个月才跳进来。但是我同意安德鲁的观点。我在此线程中尝试了原始方法。关于如何获取ID的某些信息导致它开始失败。此方法(手动直接更新字段)效果更好。至少出于我的目的。
durbnpoisn 2014年

很棒的东西。不知道您如何最终解决此问题,但是对于我的Widget的所有实例都可以正常工作。:)
Atul O Holic 2014年

这也为我工作。我以为我们需要进行广播和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);

为我工作:)


它调用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方法的含义,但嘿,它终于可以工作了:)
Henrique de Sousa 2014年

1
谢谢。我现在正在测试它,并将发布反馈。经过测试并确认工作正常。我想知道,如果有不同类型的小部件,它会一样工作吗?(+1表示工作)
Si8,2016年

我总是得到IDS 0
OMOR

这在Android Oreo上无法解决任何解决方法吗?
stickedoverflow

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(),您可以强制窗口小部件项实时获取任何新数据。


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
需要分钟-API等级:11
Anirudh拉马纳坦

太棒了 您甚至不必循环,有一个版本notifyAppWidgetViewDataChanged()需要一个数组。
劳伦斯·凯斯特洛特

2

Phaethon在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)

MyAppWidgetProvider源自AppWidgetProvider:
class MyAppWidgetProvider : AppWidgetProvider() {


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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.