android,如何检查或查找活动通知匹配自定义数据

Posted

技术标签:

【中文标题】android,如何检查或查找活动通知匹配自定义数据【英文标题】:android, how to check or find a active notification match custom data 【发布时间】:2021-07-23 23:22:52 【问题描述】:

android 应用,一个模块从远程接收不同类型的数据,并将数据传递给第 3 方通知库,以构建数据特定通知并将其发布到通知抽屉。

但是,如果稍后它接收到新数据并且如果该数据类型在通知抽屉中仍然有活动通知(用户尚未点击它),则模块需要检查并找到该类型的活动通知,并将通知标签、id 和数据传递给通知库以更新现有的活动通知。

在接收远程数据的模块中,它可以获取所有的活动通知

var foundAndReplaced = false
val activeSbn: StatusBarNotification[] = NotificationManager.getActiveNotifications()
for for (i in activeSbn.indices)  
    val id = activeSbn[i].getId()
    val tag = activeSbn[i].getTag()
    val notification: Notification = activeSbn[i].getNotification()

    val thePendingIntent: PendingIntent = notification.contentIntent()

    ///
    // check if thePendingIntent was build with same data type, how???
    // foundAndReplaced = true
    if (foundAndReplaced) 
        theNotificationHandler.repostNotification(tag, id, data)
        break
    
    ///


if (!foundAndReplaced) 
   theNotificationHandler.postNotification(data) // build and post a new notification for that data type
 

但是如何检查通知是否是具有特定数据类型的通知?

想到的是,例如接收到的数据dataType: A, latestData; B。

然后从 PendingIntent 中取出 Intent,并检查 Intent,如下所示:

/// ??? not sure how to do this, it does not have the getIntent()
var oldIntent = thePendingIntent.getIntent()
foundAndReplaced =  (oldIntent.getString(DATA_TYPE_KEY == "A") // this active notification is for the dataTYpe == A
   

并且当点击更新的通知时,intent 将被传递给 Intent 中配置的 Activity,并带有新的数据“B”。

有没有办法检查通知的pendingIntent/Intent 中的数据?或者如何根据某些数据检查通知?

编辑:总结想做的事

    当接收到来自 FCM 消息的推送通知时,通知会显示并保存在通知抽屉中(直到用户点击它)。并且在 PendingIntent 中放置一个 Intent(带有客户数据)以对用户的点击做出反应(打开一个活动并将意图传递给它,等等)
received custom data: dataType: A, latestData; Dat-A
and put in the Intent: 
val customData = "dataType: A, latestData; Dat-A"
val intent = Intent(this, PushHandlerActivity::class.java).apply 
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    putExtra(CUSTOM_MESSAGE_KEY, customData)


val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, 0)
...
and then build the notification and post it:
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        // Set the intent that will fire when the user taps the notification
        .setContentIntent(pendingIntent)
        
with(NotificationManagerCompat.from(this)) 
    notificationManager.notify(notificationId, builder.build())


    如果接收到与先前接收到的推送具有相同的自定义数据类型的新推送,并且如果先前发布的通知在通知抽屉中仍然处于活动状态(用户尚未点击它),则不应有新的通知构建并发布到通知抽屉,但它应该找出先前发布的通知(未点击并在通知抽屉中仍然处于活动状态),并更新放置在 PendingtIntent 的意图中的自定义数据。

示例。第一次拿到推送数据:dataType: A, latestData; Dat-A

稍后它会收到另一个带有数据的推送

dataType: A, latestData; Dat-B

它现在需要做的是检查活动通知(通过NotificationManager.getActiveNotifications()),查找是否有一个具有自定义数据类型==“A”的人,如果找到则更新该活动通知的意图cutomData(被额外添加)到dataType: A, latestData; Dat-B

问题出在主动通知(StatusBarNotification)可以得到pendingIntent:

val thePendingIntent: PendingIntent = aStatusBarNotification.contentIntent()

但是由于原始意图被放在了pendingIntent中(通过PendingIntent.getActivity(this, 0, intent, 0)),所以需要先从pendingIntent中取出意图。但似乎不能。

【问题讨论】:

【参考方案1】:

您无法从PendingIntent 中获取Intent

您可以在 Intents 中为不同的数据类型使用不同的 ACTION,因此当您获取特定数据类型的新数据时,您可以为该数据类型更新任何现有 PendingIntent 中的数据。只需使用PendingIntent.FLAG_UPDATE_CURRENT 更新现有PendingIntent 中的数据。

注意:我假设您在 Intent 中的“数据”存储为“附加”,而不是在 URI 字段中。


这是一个例子:

val customData = "dataType: A, latestData; Dat-A"
val customAction = "DataTypeA" // different string for each data type
                               //  ensures a unique PendingIntent for
                               //  each data type
val intent = Intent(this, PushHandlerActivity::class.java).apply 
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or
            Intent.FLAG_ACTIVITY_CLEAR_TASK
    action = customAction
    putExtra(CUSTOM_MESSAGE_KEY, customData)

// Using FLAG_UPDATE_CURRENT just updates the "extras" on an existing
//  PendingIntent
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0,
      intent, PendingIntent.FLAG_UPDATE_CURRENT)

此代码将为每种不同的数据类型创建不同的PendingIntent。但是,如果特定数据类型的PendingIntent 已经存在,这将简单地更新现有PendingIntent 中的“附加”。如果 Notification 已经存在,您甚至不必再次发布它。

【讨论】:

感谢@davidWasser!。我不确定我是否跟随你。当接收到 FCM 消息时,它可以循环通过活动通知,并检查每个通知,即val thePendingIntent: PendingIntent = notification.contentIntent()。但是如何确定这个 pendingIntent 是匹配的(针对 FCM msg 中的 dataType)?找到匹配后如何update the data in any existing PendingIntent 与来自味精的新数据? 对不起,我没有关注。我不明白你想做什么。也许用更多信息更新您的问题,包括详细信息。 我试图在编辑部分解释更多,请看看是否有意义。非常感谢! 可以为每种不同的数据类型使用不同的 notificationID 吗? 不太可能,模块构建并发布通知我相信它是随机生成的,并且数据类型涵盖了很多主题,从新闻、体育、金融、政治、生活方式等. 动态数据类型有些困难,可能是新闻,以后要更新的类型不是预先定义的。它只能从dataType 中获取密钥,然后进行搜索。

以上是关于android,如何检查或查找活动通知匹配自定义数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android活动中创建此自定义弹出消息?

Quickblox:使用自定义对象登录 (Android)

自定义android通知背景

fxcop 自定义规则 - 检查源代码以查找新关键字

如何使用自定义布局显示 Firebase 通知?

在Android中销毁布局时覆盖的方法