如何检测在 Android 中单击了通知包/组?

Sta*_*wer 12 android push-notification

在 Android Nougat 及更高版本中,应用的推送通知会在 #4th 之后自动组合在一起。

Android 中的问题是单击捆绑包不会展开推送通知列表,而是打开应用程序。

我需要识别通过推送通知打开应用程序的用户。对于单个通知,这很容易,因为我可以探索意图附加功能。捆绑包的问题在于 extras 为空,并且意图看起来与用户单击启动器图标完全相同。我无法检测到导航是通过推送通知完成的 :(

以防万一不清楚:我没有明确使用推送通知组,这是由 Android 自动完成的。我没有为通知设置任何组密钥。

我正在使用 Firebase。我只NotificationCompat在应用程序在前台时使用构建推送通知,当应用程序在后台或关闭时不执行此逻辑(OnMessageReceived仅在应用程序在前台运行)。

编辑

我知道OnMessageReceived即使在后台或关闭时,我也可以更改正在执行的事件的 PN 有效负载。我想避免这种情况,因为我发现很多人抱怨在这种情况下无法到达 PN 的问题。

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

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

即使应用程序没有创建它,我也想检测用户点击分组的 PN。

Nat*_*yev 8

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()
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

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)
}
Run Code Online (Sandbox Code Playgroud)

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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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.