小部件待定意图未更新

时间:2014-10-25 10:08:38

标签: android android-widget

我有一个显示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)

我做错了什么? 提前致谢

2 个答案:

答案 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);