Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect that a notification bundle/group was clicked in Android?

In Android Nougat and above, push notifications for your app are grouped together automatically after the # 4th.

The problem in Android is that clicking on the bundle does not expand the push notification list, it opens the app.

I have a requirement to identify users that opened the app trough a push notification. For individual notifications, this is easy since I can explore intent extras. The problem with the bundle is that extras are null and intent looks exactly the same as if the user clicked on the launcher icon. I have no way to detect that navigation was done from a push notification :(

Just in case it's not clear: I'm not using push notifications groups explicitly, this is done automatically by Android. I have not set any group key to the notifications.

I'm using Firebase. I only build the push notification using NotificationCompat when the app is on the foreground, this logic is not executed when the app is on the background or closed (OnMessageReceived only runs with the app in foreground).

EDIT

I know that I could change the PN payload for the event OnMessageReceived being executed even in the background or closed. I would like to avoid this since I have found a lot of people complaining about problems with PN not arriving in this case.

http://github.com/firebase/quickstart-android/issues/368

http://github.com/firebase/quickstart-android/issues/219

I want to detect a user tapping on a grouped PN even if the app didn't create it.

like image 497
StackOverflower Avatar asked Dec 27 '19 16:12

StackOverflower


People also ask

How can I get a list of notifications?

Scroll down and long-press the “Settings” widget, then place it on your home screen. You'll get a list of features that the Settings shortcut can access. Tap “Notification Log.” Tap the widget and scroll through your past notifications.


1 Answers

Solution 1: If you handle creation of the notifications, you can try following steps:

First of all, every time when you create new notification, you can group them by same key using setGroup(...):

val newMessageNotification1 = NotificationCompat.Builder(applicationContext, ...)
    ...
    .setGroup("group_messages")
    .build()

As you grouped notifications by same id ("group_messages"), now you can create summary notification with different intent:

val notifyIntent = Intent(this, ResultActivity::class.java).apply {
val notifyIntent = Intent(this, ResultActivity::class.java).apply {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val notifyPendingIntent = PendingIntent.getActivity(
    this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT
)

val summaryNotification = NotificationCompat.Builder(applicationContext, ...)
    .setSmallIcon(android.R.drawable.ic_btn_speak_now)
    .setContentIntent(notifyPendingIntent)
    .setContentTitle("Grouped notification title")
    .setContentText("Grouped notification text")
    .setGroup("group_messages")
    .setGroupSummary(true)
    .build()

As last step, you can have if check to make sure you have more than 1 notifications with same group, and then notify with group notification:

val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

val notificationManagerCompat = NotificationManagerCompat.from(applicationContext)
notificationManagerCompat.notify(ID, newMessageNotification1)

val amountOfNotificationsInSameGroup = notificationManager.activeNotifications
                    // Here we filter notifications that are under same group
                    .filter { it.notification.group == "group_messages" }
                    .size

if (amountOfNotificationsInSameGroup >= 2) {
    // if we already have minimum of 2 notifications, we'll group them under summary notification
    notificationManagerCompat.notify(SUMMARY_NOTIFICATION_ID, summaryNotification)
}

You can combine the code in your onMessageReceived method. As you can see, now you can have custom intent to handle grouped notifications. You can read more about grouped notifications here.

Solution 2: If you don't want to handle creation of notifications and still want to know if the notifications are grouped, you can try following solution:

NotificationManager has getActiveNotifications() function which will return notifications that have been posted by the calling app and hasn't been dismissed by the user yet. When you click grouped notifications in Android, notifications won't be dismissed. Therefore, you can check size of active notifications in your launcher activity to detect if the app was launched by clicking to grouped/bundle notifications:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val notificationManager =
            applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        if (notificationManager.activeNotifications.size >= 4) {
            // Notifications are grouped
            // Put your logic here

            // Do not forget to clear notifications
            NotificationManagerCompat.from(this).cancelAll()
        }
    }
}

Personally, I'd prefer first solution, but according to the issues you have posted, you can use second option as well but note that you won't be able to differentiate if the app was launched from launcher or by clicking grouped notification.

With second solution there might be following questions:

Q1: How can I differentiate normal notification click from group one in same activity?

- Simply you can define click_action and forward normal notification clicks to different activity. Check the docs.

If you want to replace previous notifications, you can also define same tag in your notification JSON on backend side. In this way, notifications won't be bundled because newer notifications will replace the old one with same tag. Check the docs.

I hope my answer helps.

like image 181
Natig Babayev Avatar answered Sep 24 '22 17:09

Natig Babayev