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

Posted

技术标签:

【中文标题】如何检测在 Android 中单击了通知包/组?【英文标题】:How to detect that a notification bundle/group was clicked in Android? 【发布时间】:2019-12-27 16:51:20 【问题描述】:

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

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,即使它不是应用创建的。

【问题讨论】:

AFAIK,点击捆绑包的 V 形图标应该展开/折叠通知列表。 @Edric:没错……但我不能强迫用户这样做。有些用户会点击折叠的推送通知,我想处理这种情况。 通过服务器端而不是客户端生成的通知,您的意思是您正在使用 FCM,对吗?即使在这种情况下,您仍在使用developer.android.com/reference/android/app/…,对吗?你能分享一些代码sn-p吗? @ArnabSaha:我不能,因为当应用程序在后台或关闭时,我构建通知的代码不会运行 你知道通知何时分组吗? 【参考方案1】:

解决方案 1: 如果您处理通知的创建,您可以尝试以下步骤:

首先,每次创建新通知时,都可以使用setGroup(...)按相同的键对它们进行分组:

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

当您按相同的 ID ("group_messages") 对通知进行分组时,现在您可以创建具有不同意图的摘要通知:

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()

作为最后一步,您可以让if 检查以确保您有多个同组通知,然后通过组通知进行通知:

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)

您可以在 onMessageReceived 方法中组合代码。如您所见,现在您可以使用自定义意图来处理分组通知。你可以阅读更多关于分组通知here。

解决方案 2: 如果您不想处理通知的创建,但仍想知道通知是否已分组,您可以尝试以下解决方案: p>

NotificationManager 具有getActiveNotifications() 函数,该函数将返回已由调用应用程序发布且尚未被用户关闭的通知。当您在 Android 中单击分组通知时,通知不会被关闭。因此,您可以在启动器活动中检查活动通知的大小,以检测应用程序是否已通过单击分组/捆绑通知来启动:

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()
        
    

就个人而言,我更喜欢第一个解决方案,但根据您发布的问题,您也可以使用第二个选项,但请注意,如果应用程序是从启动器启动或单击分组启动,您将无法区分通知。

使用第二种解决方案可能会有以下问题:

Q1:如何区分正常的通知点击和同一活动中的第一组?

- 只需定义click_action 并将正常的通知点击转发到不同的活动。检查docs。

如果您想替换以前的通知,您也可以在后端的通知 JSON 中定义相同的tag。这样,通知将不会被捆绑,因为较新的通知将用相同的标签替换旧通知。检查docs。

希望我的回答对你有帮助。

【讨论】:

我只在应用程序处于前台时才显示 PN。关闭应用程序时不执行方法OnMessageReceived 。我看过文档指出,即使我设法让应用在应用关闭或后台处理 PN,它也不能很好地工作。 它确实有效。可能你没有正确使用它。您能否输入您的代码并参考说明您无法手动创建通知的文档? @***er 您可以在 firbebase 中使用数据消息,这样即使应用程序在 onMessageReceived 方法上被杀死,您也可以创建通知 一些例子:github.com/firebase/quickstart-android/issues/368, github.com/firebase/quickstart-android/issues/219 您共享的链接并不是说不推荐,而且似乎问题在少数设备上发生。您是如何在应用中实现通知的?【参考方案2】:

@Natig Babayev 的回答得到了很好的解释。但是,在第二部分中,他没有解释通过单击启动器图标还是单击推送通知捆绑来区分应用程序是否打开的方法(考虑自动分组的 5 个通知的情况,但用户启动了通过单击应用程序启动器而不是通知包来应用程序。)

一种解决方案可能是禁用自动分组通知。但是,这是不可能的。参考this question和this one too

我研究了许多不同的选项,发现最好的解决方案是在 android 系统进行通知之前自行将通知分组将通知数量限制为最大未分组通知通过删除旧通知或将它们捆绑在一个单独的包中。

您也可以参考以下

    https://***.com/a/47073575/9640177 https://***.com/a/34961716/9640177

【讨论】:

以上是关于如何检测在 Android 中单击了通知包/组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中检测来自WebView的通知?

Android:如何检测通知ID是不是存在?

Android:如何通过通知下拉菜单检测设置何时更改?

Android:单击片段中的按钮时如何通知活动? [复制]

如何在类似按钮单击android时通知其他屏幕

如何从使用 PushSharp 发送的通知中检测 android 应用程序是不是已打开?