我有一个显示10张图片的小部件。在单击其中一个图像时,它会打开一个活动,显示与该图像对应的一些信息。数据存储在sqlite数据库中。
每周,这些图像都会发生变化(其中包含大约100个不同的对象,每周都会显示另外一个对象)。
我的onUpdate方法如下所示:
List<Champion> champions = // a list of 10 champions out of 100 fetched from db
int[] imageIds = // drawable ids for the 10 champions
// creating the pending intents
PendingIntent[] pIntents = new PendingIntent[champions.size()];
for(int i = 0; i < champions.size(); i++)
{
Intent intent = new Intent(context, ChampionActivity.class);
intent.putExtra(ChampionActivity.KEY_ID, champions.get(i).getChampionId());
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pIntents[i] = PendingIntent.getActivity(context, i, intent, 0);
}
// updating widgets with the new images and intents
for(int widgetId : appWidgetIds)
{
RemoteViews view = new RemoteViews(
context.getPackageName(),
R.layout.widget
);
for(int i = 0; i < imageViewIds.length; i++)
{
view.setImageViewResource(imageViewIds[i], imageIds[i]);
view.setOnClickPendingIntent(imageViewIds[i], pIntents[i]);
}
appWidgetManager.updateAppWidget(widgetId, view);
}
此小部件设置为每30分钟更新一次。图像的更新工作正常,但不知何故待处理的意图似乎没有更新。
例:
- 当显示冠军A时,用户将小部件添加到他的主屏幕
- 30分钟后,冠军A被冠军B取代,图像相应更新
- 点击冠军B仍然引导用户获得冠军A(意图额外是A的ID,而不是id ob B)
我做错了什么? 提前致谢
答案 0 :(得分:5)
这是一个常见的错误,即你的问题就在这一行:
pIntents[i] = PendingIntent.getActivity(context, i, intent, 0);
具体来说,问题在于requestCode
:它在窗口小部件的生命周期中是不变的。因此,平台无法将新Intent
识别为“新”,并且将始终提供相同(即第一个)PendingIntent
。如果您希望提供新的Intent
,则需要使用新的请求代码。来自docs:
...为了检索PendingIntent,知道两个Intent何时被认为是相同的是很重要的。人们常犯的一个错误就是使用Intents创建多个PendingIntent对象,这些对象只在其“额外”内容中有所不同,期望每次都获得不同的PendingIntent。这不会发生。用于匹配的Intent部分与Intent.filterEquals定义的部分相同。如果你使用两个与Intent.filterEquals相同的Intent对象,那么你将获得两个相同的PendingIntent。
champions.get(i).getChampionId()
的返回值类型是什么?如果这是一个int
,那看起来像是一个很好的候选者,可以用作请求代码。所以,使用
pIntents[i] = PendingIntent.getActivity(context, champions.get(i).getChampionId(), intent, 0);
可能会解决问题。
希望这有帮助。
答案 1 :(得分:4)
为了更新PendingIntent中的额外数据(如果已存在),您可以使用PendingIntent.FLAG_UPDATE_CURRENT标志。由于您一次只需要一个待处理的待处理意图,因此更合适。请记住传递相同的请求代码。请求代码可以是appWidgetId
,以便在多个实例的情况下使其唯一。 [感谢@shoerat精确定位问题]。来自docs:
表示如果描述的PendingIntent已存在的标志, 然后保留它,但用这个新的东西替换它的额外数据 意图。与getActivity(Context,int,Intent,int)一起使用, getBroadcast(Context,int,Intent,int)和getService(Context,int, 意图,int)。
如果您要创建仅包含附加内容的意图,则可以使用此选项 改变,并不关心任何收到你以前的实体 PendingIntent将能够使用您的新演员启动它,即使 他们没有明确给予它。
以下是代码:
Intent intent = new Intent(context, ChampionActivity.class);
intent.putExtra("widgetId", appWidgetId);
pIntents[i] = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);