我已经看到很多类似的问题,而且我一遍又一遍地看到相同的答案.我不想为我的应用拥有的每一种小部件都提供一个服务,尤其是看到我的应用已经有 2 个持久服务.
I have seen many questions along these lines, and I keep seeing the same answer over and over. I don't want to have to have a Service for every kind of widget my app has, especially seeing as my app already has 2 persistent services.
具体来说,如果我的现有服务之一发现数据已更改,我想更新我的小部件.在计时器上执行此操作很烦人,因为更新之间可能需要几天时间,或者一小时内可能会有好几次.我希望我的小部件始终显示最新信息.
Specifically, if one of my existing services sees that data has changed, I want to update my widgets. Doing this on a timer is annoying, as it could be days between updates or there might be several within one hour. I want my widgets to ALWAYS show up to date information.
Android 小部件设计似乎是在您的小部件在需要时提取信息的基础上工作的,我认为有许多明智的场景是活动可能希望将数据推送到小部件.
Android widget design seems to work on the basis that your widget pulls information when it wants it, I think there are many sensible scenarios where an activity may wish to push data to a widget.
阅读下面的答案,了解我如何准确地做到这一点.据我所知,如果处理得当,不会有任何不良影响.
Read the answer below for how I worked out how to do precisely this. As far as I can see there are no adverse effects if it is done properly.
要强制更新特定小部件提供程序的小部件,我们需要执行以下操作:
To force our widgets for a particular widget provider to be updated, we will need to do the following:
第 1 步 - 设置我们的 AppWidgetProvider
我不会详细介绍如何创建 info xml 文件或更改 Android Manifest - 如果您不知道如何正确创建小部件,那么您应该先阅读大量教程.
I will not go through the details of creating the info xml file or changes to the Android Manifest - if you don't know how to create a widget properly, then there are plenty of tutorials out there you should read first.
这是一个示例 AppWidgetProvider
类:
public class MyWidgetProvider extends AppWidgetProvider {
public static final String WIDGET_IDS_KEY ="mywidgetproviderwidgetids";
public static final String WIDGET_DATA_KEY ="mywidgetproviderwidgetdata";
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra(WIDGET_IDS_KEY)) {
int[] ids = intent.getExtras().getIntArray(WIDGET_IDS_KEY);
if (intent.hasExtra(WIDGET_DATA_KEY)) {
Object data = intent.getExtras().getParcelable(WIDGET_DATA_KEY);
this.update(context, AppWidgetManager.getInstance(context), ids, data);
} else {
this.onUpdate(context, AppWidgetManager.getInstance(context), ids);
}
} else super.onReceive(context, intent);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
update(context, appWidgetManager, appWidgetIds, null);
}
//This is where we do the actual updating
public void update(Context context, AppWidgetmanager manager, int[] ids, Object data) {
//data will contain some predetermined data, but it may be null
for (int widgetId : ids) {
.
.
//Update Widget here
.
.
manager.updateAppWidget(widgetId, remoteViews);
}
}
第 2 步 - 发送广播
在这里我们可以创建一个静态方法来更新我们的小部件.在小部件更新操作中使用我们自己的键很重要,如果我们使用 AppWidgetmanager.EXTRA_WIDGET_IDS,我们不仅会破坏我们自己的小部件,还会破坏其他小部件.
Here we can create a static method that will get our widgets to update. It is important that we use our own keys with the widget update action, if we use AppWidgetmanager.EXTRA_WIDGET_IDS we will not only break our own widget, but others as well.
public static void updateMyWidgets(Context context, Parcelable data) {
AppWidgetManager man = AppWidgetManager.getInstance(context);
int[] ids = man.getAppWidgetIds(
new ComponentName(context,MyWidgetProvider.class));
Intent updateIntent = new Intent();
updateIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
updateIntent.putExtra(MyWidgetProvider.WIDGET_ID_KEY, ids);
updateIntent.putExtra(MyWidgetProvider.WIDGET_DATA_KEY, data);
context.sendBroadcast(updateIntent);
}
如果将此方法与多个提供商一起使用,请确保他们使用不同的密钥.否则,您可能会发现小部件 a 的代码正在更新小部件 b,这可能会产生一些奇怪的后果.
If using this method with multiple providers MAKE SURE they use different keys. Otherwise you may find widget a's code updating widget b and that can have some bizarre consequences.
第 3 步 - 点击更新
另一件好事是让我们的小部件在被点击时神奇地更新.将以下代码添加到更新方法中以实现此目的:
Another nice thing to do is to get our widget to update magiacally whenever it is clicked. Add the following code into the update method to acheive this:
RemoteViews views =
new RemoteViews(context.getPackageName(),R.layout.mywidget_layout);
Intent updateIntent = new Intent();
updateIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
updateIntent.putExtra(myWidgetProvider.WIDGET_IDS_KEY, ids);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, 0, updateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.view_container, pendingIntent);
此代码将导致在单击小部件时调用 onUpdate 方法.
This code will cause the onUpdate method to be called whenever the widget is clicked on.
备注
这篇关于Android:如何强制更新特定类型的所有小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!