Android 通知 addAction 未启动广播
Android notification addAction not launching broadcast
正在创建通知:
PendingIntent pIntent = PendingIntent.getActivity(context, (int) taskId, intent, 0);
intent.setAction(Utils.MARK_AS_DONE);
PendingIntent pIntentMarkAsDone = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setTicker(ticker)
.setContentTitle(title)
.setContentText(description)
.setSmallIcon(getAlarmIcon(type))
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_launcher))
.setContentIntent(pIntent)
.addAction(0, context.getString(R.string.mark_as_done), pIntentMarkAsDone);
Notification notification = builder.build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify((int) taskId, notification);
我使用 getBroadcast 的待定意图添加了添加。
接收者:
public class NotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Log to check
}
}
这个class应该"receive"的动作。我还添加了 Manifest
清单:
<receiver android:name=".NotificationReceiver">
<intent-filter>
<action android:name="<package_name>.MARK_AS_DONE"/>
</intent-filter>
</receiver>
嗯,onReceive 没有接收。我做错了什么?
TL;DR:创建一个新的 Intent
,而不是重复使用 intent
中的那个,并从 <receiver>
中删除 <intent-filter>
。
你的第一行是:
PendingIntent pIntent = PendingIntent.getActivity(context, (int) taskId, intent, 0);
这意味着 intent
识别了一些 activity。如果你是通过 new Intent(context, YourActivityClass.class)
创建的,那么它里面有一个 ComponentName
集,用来标识你的 activity.
然后,您在 intent
上调用 setAction()
并将其与 getBroadcast()
一起使用。但是,除了设置(或替换)操作之外,intent
中的其他所有内容都与原来相同。特别是,标识 activity 的 ComponentName
仍然存在。因此,当发送广播时,Android 无法传递它,因为组件无效(activity 无法直接接收广播),并且操作字符串被忽略(因为一旦 ComponentName
设置在 Intent
上,操作和类别等内容不再计入路由)。
因此,我建议您创建两个 Intent
对象,一个用于 activity,一个用于接收器。
请注意,您不需要接收器的操作字符串。您可以使用显式 Intent
构造函数 (new Intent(context, NotificationReceiver.class)
)。事实上,在接收器上设置操作字符串不利于安全,因为现在 any 应用程序可以向您发送该广播。因此,我建议删除 <intent-filter>
并使用明确的 Intent
来创建您的广播 PendingIntent
.
正在创建通知:
PendingIntent pIntent = PendingIntent.getActivity(context, (int) taskId, intent, 0); intent.setAction(Utils.MARK_AS_DONE); PendingIntent pIntentMarkAsDone = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(context) .setTicker(ticker) .setContentTitle(title) .setContentText(description) .setSmallIcon(getAlarmIcon(type)) .setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_launcher)) .setContentIntent(pIntent) .addAction(0, context.getString(R.string.mark_as_done), pIntentMarkAsDone); Notification notification = builder.build(); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify((int) taskId, notification);
我使用 getBroadcast 的待定意图添加了添加。
接收者:
public class NotificationReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Log to check } }
这个class应该"receive"的动作。我还添加了 Manifest
清单:
<receiver android:name=".NotificationReceiver"> <intent-filter> <action android:name="<package_name>.MARK_AS_DONE"/> </intent-filter> </receiver>
嗯,onReceive 没有接收。我做错了什么?
TL;DR:创建一个新的 Intent
,而不是重复使用 intent
中的那个,并从 <receiver>
中删除 <intent-filter>
。
你的第一行是:
PendingIntent pIntent = PendingIntent.getActivity(context, (int) taskId, intent, 0);
这意味着 intent
识别了一些 activity。如果你是通过 new Intent(context, YourActivityClass.class)
创建的,那么它里面有一个 ComponentName
集,用来标识你的 activity.
然后,您在 intent
上调用 setAction()
并将其与 getBroadcast()
一起使用。但是,除了设置(或替换)操作之外,intent
中的其他所有内容都与原来相同。特别是,标识 activity 的 ComponentName
仍然存在。因此,当发送广播时,Android 无法传递它,因为组件无效(activity 无法直接接收广播),并且操作字符串被忽略(因为一旦 ComponentName
设置在 Intent
上,操作和类别等内容不再计入路由)。
因此,我建议您创建两个 Intent
对象,一个用于 activity,一个用于接收器。
请注意,您不需要接收器的操作字符串。您可以使用显式 Intent
构造函数 (new Intent(context, NotificationReceiver.class)
)。事实上,在接收器上设置操作字符串不利于安全,因为现在 any 应用程序可以向您发送该广播。因此,我建议删除 <intent-filter>
并使用明确的 Intent
来创建您的广播 PendingIntent
.