仅窗口小部件的多个实例更新最后一个窗口小部件

Gre*_*egM 20 android android-widget

我有一个WidgetProvider和一个Configure Activity

当Widget启动时,它从configure活动开始,我通过对widgetprovider进行自定义调用来设置它

(你会注意到来自sdk教程的例子)

 // Push widget update to surface with newly set prefix
              AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
              AwarenessWidget.updateAppWidget(context, appWidgetManager,
                      mAppWidgetId, position);

            // Make sure we pass back the original appWidgetId
            Intent resultValue = new Intent();
            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
            setResult(RESULT_OK, resultValue);
            finish();
Run Code Online (Sandbox Code Playgroud)

我将Widget ID传递给函数....在widget中我创建了一个Intent,如下所示:

  Intent configIntent = new Intent(context, Configure.class);
    configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

    PendingIntent pendingIntent = PendingIntent.getActivity
    (context, 0, configIntent,
    PendingIntent.FLAG_UPDATE_CURRENT);

    views.setOnClickPendingIntent(R.id.MainImage,pendingIntent);

    views.setImageViewResource(R.id.MainImage, lv_images[version]);

    appWidgetManager.updateAppWidget(appWidgetId, views);
Run Code Online (Sandbox Code Playgroud)

我总是引用窗口小部件ID,甚至将其添加为意图的额外内容,但是当我在主屏幕上获得其中两个小部件时,窗口小部件ID始终引用最后放置的窗口小部件ID

Sna*_*ler 51

我遇到了类似的问题.只需将此添加到您的配置活动中,您可以在其中设置PendingIntent:

Uri data = Uri.withAppendedPath(
    Uri.parse(URI_SCHEME + "://widget/id/")
    ,String.valueOf(appWidgetId));
intent.setData(data);
Run Code Online (Sandbox Code Playgroud)

变量URI_SCHEME是一个String,可以是你想要的任何东西..即 - "ABCD"这会导致每个小部件都有一个唯一的PendingIntent.

  • 这有效,但我不明白为什么.有人可以再解释一下这个答案吗? (2认同)

Cod*_*der 38

这里有一个更深入的解释,说明为什么你的代码不起作用以及如何修复它.从Android SDK文档:

PendingIntent本身只是对系统维护的令牌的引用,该令牌描述了用于检索它的原始数据.这意味着,即使其拥有的应用程序的进程被终止,PendingIntent本身也将保持可用于已经给出它的其他进程.如果创建应用程序稍后重新检索相同类型的PendingIntent(相同的操作,相同的Intent操作,数据,类别和组件以及相同的标志),它将接收表示相同令牌的PendingIntent,如果它仍然有效,并且可以因此调用cancel()来删除它.

由于这种行为,重要的是要知道两个Intent何时被认为是相同的,以便检索PendingIntent.人们常犯的一个错误是使用Intents创建多个PendingIntent对象,这些对象只在其"额外"内容中有所不同,期望每次都获得不同的PendingIntent.这不会发生.用于匹配的Intent部分与Intent.filterEquals定义的部分相同.如果你使用两个与Intent.filterEquals等效的Intent对象,那么你将获得两个相同的PendingIntent.

请注意,指定不同的"额外"内容是不足以使PendingIntents被视为唯一,但使用setData设置唯一URI.这就是为什么Snailer的URI解决方案"神奇地"解决了这个问题.

该文档还为该问题提供了一种不同的(可以说是更简单的)解决方案.在调用getActivity时,只需设置一个唯一的requestCode,而不是创建自定义URI:

PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Run Code Online (Sandbox Code Playgroud)

资料来源:http://developer.android.com/reference/android/app/PendingIntent.html

  • SDK当前不使用requestCode,但它确实将Intent视为唯一.文档建议这是requestCode的有效使用:"或者为getActivity提供不同的请求代码整数" (2认同)

Sea*_*ken 11

在我的测试中,使用PendingIntent上的setData(...)并不能解决运行Android 4.0.4的Verizon Thunderbolt上的问题.它适用于我的其他测试设备和模拟器.

我测试了requestCode的使用,它适用于所有情况.我只是将requestCode设置为小部件ID:

pendingIntent = PendingIntent.getService(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Run Code Online (Sandbox Code Playgroud)