我正在构建一个具有多个按钮的小部件,每个按钮都将自己的意图发送给广播接收器。广播接收器假设基于按下哪个按钮显示Toast消息。代码目前看起来像这样:
public class WidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
ComponentName thisWidget = new ComponentName(context, WidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
// Set the text of the buttons
remoteViews.setTextViewText(R.id.widgetPreset1Button, prefs.getString("widget1", "Not set"));
remoteViews.setTextViewText(R.id.widgetPreset2Button, prefs.getString("widget2", "Not set"));
remoteViews.setTextViewText(R.id.widgetPreset3Button, prefs.getString("widget3", "Not set"));
remoteViews.setTextViewText(R.id.widgetPreset4Button, prefs.getString("widget4", "Not set"));
// Register the buttons with an OnClick event
Intent intent1 = new Intent("myapp.SendWidgetPreset");
intent1.putExtra("Widget", 1);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetPreset1Button, pendingIntent1);
Intent intent2 = new Intent("myapp.SendWidgetPreset");
intent2.putExtra("Widget", 2);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetPreset2Button, pendingIntent2);
Intent intent3 = new Intent("myapp.SendWidgetPreset");
intent3.putExtra("Widget", 3);
PendingIntent pendingIntent3 = PendingIntent.getBroadcast(context, 0, intent3, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetPreset3Button, pendingIntent3);
Intent intent4 = new Intent("myapp.SendWidgetPreset");
intent4.putExtra("Widget", 4);
PendingIntent pendingIntent4 = PendingIntent.getBroadcast(context, 0, intent4, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetPreset4Button, pendingIntent4);
new WidgetBroadcastReceiver();
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
}
和BroadcastReceiver:
public class WidgetBroadcastReceiver extends BroadcastReceiver{
public WidgetBroadcastReceiver(){
}
@Override
public void onReceive(Context context, Intent arg1) {
int widget = arg1.getIntExtra("Widget", -1);
Toast.makeText(context, "Widget pressed: " + widget, Toast.LENGTH_SHORT).show();
}
}
我的问题是,无论按下哪个按钮,它始终会显示Widget pressed: 4
。如果我将四行intent4
,intent4.putExtra()
,pendingIntent4
和remoteViews.setOnClickPendingIntent()
置于所有其他意图之上,则会始终说Widget pressed: 3
。换句话说,无论最后的意图注册是什么,都是Toast消息中显示的小部件。
任何人都知道为什么这不符合我的要求?
答案 0 :(得分:16)
您需要为每个pendingintent ex提供单独的请求代码:
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 1/*request code*/, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
答案 1 :(得分:1)
你的PendingIntents被下一个被覆盖。这是因为它们比较了被封装的Intent,并且在比较Intents时不考虑额外的内容。为每个意图执行此操作:
Intent intent1 = new Intent("myapp.SendWidgetPreset");
intent1.putExtra("Widget", 1);
// This line makes your intents different
intent1.setData(Uri.parse(intent1.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetPreset1Button, pendingIntent1);
答案 2 :(得分:1)
似乎PendingIntent.getBroadcast()会忽略requestCode(与PendingIntent.getActivity不同)。
因此,要创建唯一的PendingIntents,您可以为Intent提供数据。
示例:
public static Intent makeUniqueIntent(String action, int requestCode) {
Intent intent = new Intent(action);
intent.setData(Uri.parse("http://"+ String.valueOf(requestCode)));
return intent;
}
然后按照惯例制作你的Pending Intent,包括requestCode。
PendingIntent.getBroadcast(ctx, request_code,
makeUniqueIntent(NotificationReceiver.INTENT, request_code),
PendingIntent.FLAG_CANCEL_CURRENT);
在Intent中有一个Data元素,AndroidManifest.xml中匹配的Intent Filter也必须有一个Data元素:
<receiver android:name=".service.NotificationReceiver">
<intent-filter>
<action android:name="my.package.my_action_string"/>
<data android:scheme="http"/>
</intent-filter>
</receiver>
上述意图过滤器仅用于识别方案(即&#34; http&#34;)。因此,任何具有该方案的Uri都将匹配此过滤器&#34;数据&#34;将调用元素和相应的Receiver类。
注意:
有关使用意图过滤器进行数据测试的更多信息:
http://developer.android.com/guide/components/intents-filters.html#DataTest