点击安卓通知图标无法触发广播接收器。

9
我有一个与推送通知相关的应用程序。当用户点击通知时,我希望触发广播接收器而不是活动。
我查看了这些线程,看起来这是完全可能和常见的。 Android Notification Action is not fired (PendingIntent) Send broadcast on notification click 但是我无法让它工作。我看到通知,但是当我点击它时,它从未触发我的广播接收器。
这是我尝试过的:
  1. I created a custom receiver:

    public class NotificationOnClickReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(final Context context, Intent intent) {
            Log.d(Constants.Engine.LOGGER_TAG_GCM,
                    NotificationOnClickReceiver.class.toString() + " triggered");
        }
    }
    
  2. I registered this receiver dynamically on my global Application (not activity)

    mNotificationOnClickReceiver = new NotificationOnClickReceiver();
    IntentFilter intentFilterOnClick = new IntentFilter(Constants.Engine.BROADCAST_RECEIVER_FILTER_NOTIFICATION_ONCLICK);
    getApplicationContext().registerReceiver(mNotificationOnClickReceiver, intentFilterOnClick);
    Log.e(Constants.Engine.LOGGER_TAG_DBG, "mNotificationOnClickReceiver = " + mNotificationOnClickReceiver.toString());
    
过滤器只是一个字符串常量(我想知道这是否是问题)。
    public static final String BROADCAST_RECEIVER_FILTER_NOTIFICATION_ONCLICK = "push_notification.onclick";
  1. Receiver intent setup:

    // When the user taps on the notification bar, this is the receiver that I want to be called
    Intent pushNotificationIntent;
    Log.e(Constants.Engine.LOGGER_TAG_DBG, "Notification called!");
    pushNotificationIntent = new Intent(this, NotificationOnClickReceiver.class);
    // Not sure if this causing the problem
    pushNotificationIntent.setAction(Constants.Engine.BROADCAST_RECEIVER_FILTER_NOTIFICATION_ONCLICK);
    // ensures that each notification and intent are unique
    int uniqueCode = new Random().nextInt(Integer.MAX_VALUE);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            context,
            uniqueCode,
            pushNotificationIntent, // Receiver Intent
            PendingIntent.FLAG_CANCEL_CURRENT);
    Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
            .setSmallIcon(mIconId)
            .setContentTitle(context.getString(R.string.myString))
            .setContentText("My GCM Alert!")
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);
    
  2. From the logs, things seem to work except that my Broadcast receiver never gets called:

    02-22 15:47:47.092 16863-16863/com.myapp.test E/MYAPP_DBG: mNotificationOnClickReceiver = mytest.broadcastreceivers.NotificationOnClickReceiver@d78f559
    02-22 15:47:53.312 16863-17038/com.myapp.test E/MYAPP_DBG: Notification called!
    
如果有人已经做好了这个,你能给我指出一个样例代码吗?我不知道我的bug在哪里。谢谢!
2个回答

18
这似乎是问题所在:
pushNotificationIntent = new Intent(this, NotificationOnClickReceiver.class);

你实际上是为广播PendingIntent创建了一个显式的Intent。显式Intent不能与动态注册的接收器一起使用,因为它们针对的是Receiver类而不是实例。

你需要改用隐式Intent,只需通过将Intent实例化为动作String而不是ContextClass即可。例如:

pushNotificationIntent = new Intent(Constants.Engine.BROADCAST_RECEIVER_FILTER_NOTIFICATION_ONCLICK);
请注意,如果您的应用程序进程在单击“Notification”之前被杀死,那么动态注册的接收器实例也会随之消失,而且“Notification”的广播将不会有任何作用。
根据所需的行为,将Receiver类静态注册到清单中并保持显式Intent可能更好。这样做将允许您的应用程序接收通知广播,即使其进程已被杀死。
要做到这一点,您只需要在清单中添加一个接收器元素,用于NotificationOnClickReceiver。
<receiver android:name="NotificationOnClickReceiver" />

虽然你仍然可以在该广播Intent上设置一个操作,但是在这里你不需要一个,因为显式的Intent已经直接针对该类进行了目标定位。如果接收器仅用于一个功能,则不一定需要该操作,可以完全删除它。

然后,您可以删除步骤2中的代码,因为您不再需要动态注册的实例。


1

发送广播使用以下代码:sendBroadcast(new Intent("NotificationClicked"));

要接收广播,在清单文件的应用程序标签中添加以下内容。

<receiver android:name=".NotificationOnClickReceiver" >
            <intent-filter>
                <action android:name="NotificationClicked" >
                </action>
            </intent-filter>
        </receiver>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接