我已经看到了很多这样的问题,我一遍又一遍地看到同样的答案.我不想为我的应用程序拥有的每种小部件都有一个服务,特别是因为我的应用程序已经拥有2个持久服务.
具体来说,如果我的一个现有服务看到数据已更改,我想更新我的小部件.在计时器上执行此操作很烦人,因为它可能是更新之间的天数,或者在一小时内可能有几天.我希望我的小部件始终显示最新信息.
Android小部件设计似乎是基于您的小部件在需要时提取信息的基础上工作,我认为有许多明智的场景,其中活动可能希望将数据推送到小部件.
阅读下面的答案,了解我是如何做到这一点的.据我所知,如果做得好,没有任何不利影响.
Chr*_*dus 37
要强制更新特定窗口小部件提供程序的窗口小部件,我们需要执行以下操作:
第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);
}
}
Run Code Online (Sandbox Code Playgroud)
第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);
}
Run Code Online (Sandbox Code Playgroud)
如果将此方法与多个提供程序一起使用,请确保它们使用不同的密钥.否则,您可能会发现widget a的代码更新小部件b,这可能会产生一些奇怪的后果.
第3步 - 点击更新
另一件好事是让我们的小部件在点击时进行恶意更新.将以下代码添加到update方法中以实现此目的:
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);
Run Code Online (Sandbox Code Playgroud)
此代码将导致在单击窗口小部件时调用onUpdate方法.
笔记
很抱歉OP的答案迟到了,但对于其他人来说,您可以使用这样的方法来更新特定类型的所有应用程序小部件(布局和类):
public static void updateAllWidgets(final Context context,
final int layoutResourceId,
final Class< ? extends AppWidgetProvider> appWidgetClass)
{
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), layoutResourceId);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
final int[] appWidgetIds = manager.getAppWidgetIds(new ComponentName(context, appWidgetClass));
for (int i = 0; i < appWidgetIds.length; ++i)
{
manager.updateAppWidget(appWidgetIds[i], remoteViews);
}
}
Run Code Online (Sandbox Code Playgroud)
它的作用是RemoteViews为您的布局创建一个 ,然后获取AppWidgetManager并找到您提供的类的所有应用程序小部件,迭代它们并更新它们。
| 归档时间: |
|
| 查看次数: |
22244 次 |
| 最近记录: |