微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android:如何强制更新特定类型的所有小部件

我已经看到了很多这样的问题,我一遍又一遍地看到同样的答案.我不想为我的应用程序拥有的每种小部件都有一个服务,特别是因为我的应用程序已经拥有2个持久服务.

具体来说,如果我的一个现有服务看到数据已更改,我想更新我的小部件.在计时器上执行此操作很烦人,因为它可能是更新之间的天数,也可能在一小时内有几天.我希望我的小部件始终显示最新信息.

Android小部件设计似乎是基于您的小部件在需要时提取信息的基础上工作,我认为有许多明智的场景,其中活动可能希望将数据推送到小部件.

阅读下面的答案,了解我是如何做到这一点的.据我所知,如果做得好,没有任何不利影响.

解决方法:

要强制更新特定窗口小部件提供程序的窗口小部件,我们需要执行以下操作:

>设置我们的提供商以接收专门的广播
>发送专业广播:

>与提供者关联的所有当前窗口小部件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);
}

如果将此方法与多个提供程序一起使用,请确保它们使用不同的密钥.否则,您可能会发现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);

代码将导致在单击窗口小部件时调用onUpdate方法.

笔记

>对updateWidgets()的任何调用都将导致更新我们窗口小部件的所有实例.
>单击窗口小部件将导致窗口小部件的所有实例都更新
>无需服务
>当然,小心不要经常更新 – 小部件更新使用电池电量.
>请记住,所有窗口小部件提供程序都会收到广播,并且它的特殊键确保它只是我们实际更新的窗口小部件.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐