jeanluc rotolo
jeanluc rotolo

Reputation: 195

How can I create multiple grouped notifications with individual pending intents

So the issue I am getting is that notifications with pending intents are not sharing the correct intent extras which in turn is affecting my app.

The goal is to be able to create multiple grouped notifications with their own pending intents. I understand that not all notifications require intents however in my case each notification clicked leads to a specific area in the app.

I have tried changing the intent flags but still get the same issue.

Notification creation :

PendingIntent dismissIntent = createDismissIntent(uniqueID, notification.getGroup());

notificationBuilder.setSmallIcon(smallIcon)
            .setContentTitle(notification.getTitle())
            .setContentText(notification.getMessage())
            //.setContentIntent(contentIntent)
            .setDeleteIntent(dismissIntent)
            .setColor(context.getColor(R.color.notificationColor))
            .setVisibility(visibility)
            .setPriority(priority)
            .setStyle(style)
            .setAutoCancel(true)
            .setGroup(notification.getGroup())
            .setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE);

    notificationManager.notify(uniqueID, notificationBuilder.build());

Method

private PendingIntent createDismissIntent(int uniqueID, String group) {
    Intent intent = new Intent(context, ActionReceiver.class).setAction(Constants.NotificationDismissIntent);
    intent.putExtra("id", uniqueID);
    intent.putExtra("group", group);
    return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

Receiver

        int uniqueID = intent.getIntExtra("id", 0);
        String group = intent.getStringExtra("group");

        if (intent.getAction().matches(Constants.NotificationDismissIntent)) {
            try {
                if (!intent.getBooleanExtra("isSummary", false)) {
                    boolean success = NotificationStorage.getInstance(context).removeNotification(group, uniqueID);
                    if (!success)
                        Log.d(FIREBASE_MESSAGING_TAG, "Failed to remove notification from storage");
                }
            }
        }

Thanks :)

Upvotes: 0

Views: 325

Answers (1)

jeanluc rotolo
jeanluc rotolo

Reputation: 195

Taken from the Pending Intent Documentation https://developer.android.com/reference/android/app/PendingIntent

A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it.

Because of this behavior, it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen. The parts of the Intent that are used for matching are the same ones defined by Intent#filterEquals(Intent). If you use two Intent objects that are equivalent as per Intent#filterEquals(Intent), then you will get the same PendingIntent for both of them.

Answer :

There are two typical ways to deal with this.

If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents. This may be any of the Intent attributes considered by Intent#filterEquals(Intent), or different request code integers supplied to getActivity(Context, int, Intent, int), getActivities(Context, int, Intent[], int), getBroadcast(Context, int, Intent, int), or getService(Context, int, Intent, int).

Upvotes: 2

Related Questions