通知监控 NotificationListenerService 的 onNotificationPosted 重复回调问题
通过 NotificationListenerService 监听第三方应用的通知发现,同一条通知,会回调两次 onNotificationPosted 方法。
```log // 第一次回调 2023-01-31 11:42:31.082330 2483 2483 I NotificationMonitorService: onNotificationPosted:StatusBarNotification(pkg=com.tencent.wemeet.app user=UserHandle{0} id=11499522 tag=null key=0|com.tencent.wemeet.app|11499522|null|10076: Notification(channel=wemeet shortcut=null contentView=null vibrate=default sound=android.resource://com.tencent.wemeet.app/2131623938 tick defaults=0x6 flags=0x11 color=0x00000000 vis=PRIVATE)) - 1 2023-01-31 11:42:31.086442 2483 2483 I NotificationMonitorReceiver: notify time: 1675136670845, pending size: 1
// 第二次回调 2023-01-31 11:42:31.088771 2483 2483 I NotificationMonitorService: onNotificationPosted:StatusBarNotification(pkg=com.tencent.wemeet.app user=UserHandle{0} id=11499522 tag=null key=0|com.tencent.wemeet.app|11499522|null|10076: Notification(channel=wemeet shortcut=null contentView=null vibrate=default sound=android.resource://com.tencent.wemeet.app/2131623938 tick defaults=0x6 flags=0x11 color=0x00000000 vis=PRIVATE)) - 1 2023-01-31 11:42:31.090506 2483 2483 I NotificationMonitorReceiver: notify time: 1675136670845, pending size: 2 ```
解决该问题的思路是如何判断两次回调的 StatusBarNotification 对象是同一个通知。
经过日志分析,onNotificationPosted 的时间戳相差毫秒级别,且两次 StatusBarNotification 对象的 postTime 是相同的。
通过记录上一次 StatusBarNotification 对象,并与第二次的 StatusBarNotification 对象进行比较去重,
StatusBarNotification 对象有个属性 key,可以作为唯一识别符:
java
private String key() {
String sbnKey = user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid;
if (overrideGroupKey != null && getNotification().isGroupSummary()) {
sbnKey = sbnKey + "|" + overrideGroupKey;
}
return sbnKey;
}
并配合 postTime 属性进行去重:
kotlin
// 过滤同一条通知
if (lastSbn?.key == sbn.key && lastSbn?.postTime == sbn.postTime) {
return
}
当然,如果你知道一些 Intent 中的额外信息,也可以作为过滤条件:
kotlin
val text = extras.getString(Notification.EXTRA_TEXT)
val title = extras.getString(Notification.EXTRA_TITLE)
// other ...
- 通知监控 NotificationListenerService 的 onNotificationPosted 重复回调问题
- Android View 知识体系
- Kotlin 协程的取消机制超详细解读
- Android ViewPager2 使用 自定义指示器视图
- Android ViewModel 超详细分析
- Android 无障碍监听通知的过程
- ADB 模拟输入事件总结
- Android 单元测试基础
- Java 多线程并发【13】FutureTask
- Android UI 测试基础
- Android 无障碍全局悬浮窗实现方案
- Java 多线程并发 【11】ReentrantReadWriteLock
- Java 多线程并发 【10】ReentrantLock
- Java 多线程并发【8】LockSupport
- Java 多线程并发【4】虚拟机锁优化方案
- 散列表 及其在 JDK 中的实现
- Android 应用架构指南
- Kotlin/Java 数据类型的底层逻辑
- Android 主线程一定是 UI 线程吗?
- Context.getSystemService 获取 Manager 的底层实现