[记录]在android应用中,多个widget分别更新的解决记录

之前写了一个天气预报的android应用,已经放在一些应用市场供人下载使用了。最近在完善这个应用,之前的桌面widget功能只能显示一个地区的天气信息,现在想提供可同时显示多个地区的天气信息的功能。

思路很简单,大致就是:记录不同widget的id和对应的地区信息,然后就根据这个进行显示。

本来以为很简单,直接在PendingIntent中加入widget的id然后进行传递就行了;但是在实现时,却发现:从intent取到的值几乎总是最后一个widget的Id值,始终无法取到正确的widget的id值?!问题出现在哪里呢?

经过对PendingIntent的文档查看:

A description of an Intent and target action to perform with it. Instances of this class are created withgetActivity(Context, int, Intent, int)getActivities(Context, int, Intent[], int),getBroadcast(Context, int, Intent, int), and getService(Context, int, Intent, int); the returned object can be handed to other applications so that they can perform the action you described on your behalf at a later time.

By giving a PendingIntent to another application, you are granting it the right to perform the operation you have specified as if the other application was yourself (with the same permissions and identity). As such, you should be careful about how you build the PendingIntent: often, for example, the base Intent you supply will have the component name explicitly set to one of your own components, to ensure it is ultimately sent there and nowhere else.

A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus callcancel() to remove it.

Because of this behavior, it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This doesnot happen. The parts of the Intent that are used for matching are the same ones defined byIntent.filterEquals. If you use two Intent objects that are equivalent as per Intent.filterEquals, then you will get the same PendingIntent for both of them.

There are two typical ways to deal with this.

If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents. This may be any of the Intent attributes considered by Intent.filterEquals, or different request code integers supplied to getActivity(Context, int, Intent, int)getActivities(Context, int, Intent[], int)getBroadcast(Context, int, Intent, int), orgetService(Context, int, Intent, int).

If you only need one PendingIntent active at a time for any of the Intents you will use, then you can alternatively use the flags FLAG_CANCEL_CURRENT or FLAG_UPDATE_CURRENT to either cancel or modify whatever current PendingIntent is associated with the Intent you are supplying.

原文地址在这里

根据上文,个人理解为:在某些情况下(operation、action、data等相同)PendingIntent将会复用;所以,在前面总是取到最后一个widget的id的值,很可能就是因为PendingIntent复用的原因。在我的应用中,action不能变,所以尝试改变了data(Uri),把我的包名作为uri前缀:com.xidige.weather;为了不跟其他的混在一起,特意随便加上一些内容,最后的uri就类似这样:com.xidige.weather://widget/id/***。在经过上面的修改后,可以正确取到widget的id值了。

这里贴上部分代码:

Intent intent=new Intent(context, MainActivity.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
//下面这个是为了能区分各个widget的pendingintent
intent.setData(Uri.withAppendedPath(Uri.parse("com.xidige.weather://widgets/id/"+widgetId),String.valueOf(widgetId)));
// intent.putExtra(INTENT_KEY_WIDGETID, widgetId);
//这个标志让activity能接收到intent传的数据: PendingIntent.FLAG_UPDATE_CURRENT
PendingIntent pendingIntent=PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

 

» 本文链接地址:https://www.xidige.com/274

打开支付宝扫一扫,即可进行扫码打赏哦

扫码支持
扫码打赏,你说多少就多少

标签:

分享到:

扫一扫 在手机阅读、分享本文

上一篇: 下一篇:
评论区0人评论198人参与

电子邮件地址不会被公开。 必填项已用*标注

*

loading

赞助商广告