通知監控 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 的底層實現