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.