要强制更新特定小部件提供程序的小部件,我们需要执行以下操作:
- 设置我们的提供商以接收专门的广播
- 发送专用广播:
- 所有当前的小部件 ID 都与提供者关联
- 要发送的数据
- 只有我们的提供商才会响应的键(重要!)
- 让我们的小部件在点击时更新(没有服务!)
第 1 步 - 设置我们的 AppWidgetProvider
我不会详细介绍如何创建 info xml 文件或更改 Android Manifest - 如果您不知道如何正确创建小部件,那么您应该先阅读大量教程。
这是一个示例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,我们不仅会破坏我们自己的小部件,还会破坏其他小部件。
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,这可能会产生一些奇怪的后果。
第 3 步 - 点击更新
另一件好事是让我们的小部件在被点击时神奇地更新。将以下代码添加到更新方法中以实现此目的:
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 方法。
备注
- 对 updateWidgets() 的任何调用都会导致我们的小部件的所有实例都被更新。
- 单击小部件将导致我们的小部件的所有实例都被更新
- 无需服务
- 当然,请注意不要经常更新 - 小部件更新会消耗电池电量。
- 请记住,广播是由所有小部件提供者接收的,它是我们的特殊密钥,可确保只有我们的小部件实际更新。