Skip to content

[BUG] duplicate notifications were sent #1

@beyond-far

Description

@beyond-far

duplicate notifications were sent each time, and the reason maybe android itself sent silent notification update for certain reason, according to gemini's response (attached).

So, maybe hash(pkg | id | tag | user) is necessary.

Logical Fallacies & Premise Identification

  1. Definitional Error: You are conflating "Notification Updates" with "Duplicate Notifications." At the Android Framework level, onNotificationPosted frequency maps to NotificationManager.notify() calls, not to the number of visual alerts perceived by the user.
  2. Missing Premise: You fail to distinguish between the StatusBarNotification (SBN) unique identifier (Key) and its payload. The fact that multiple apps exhibit this behavior confirms it is an intended API design, not a logic error.
  3. Information Deficit: You have omitted critical context regarding Android OS versions and specific OEMs (e.g., Xiaomi, Huawei). OEM-specific notification proxies often re-trigger or re-sort notifications, causing redundant callbacks to the listener.

Core Cause Analysis

  1. Atomic Update Mechanism: When a source app calls notify(ID, notification) and the ID already exists, the system performs an update. Even if content changes are negligible (e.g., progress bar increments or foreground service heartbeats), onNotificationPosted is triggered.
  2. Ranking Updates: The system re-evaluates notification priority based on user interaction or internal algorithms. Any change in the global notification rank can trigger a callback to synchronize the listener's state.
  3. Multi-User/Profile Environments: Notifications originating from different UserHandle contexts (e.g., Work Profiles) may be dispatched multiple times depending on the listener's permission scope.
  4. Lack of Built-in Mutex: NotificationListenerService provides no native deduplication. Failure to compare SBN.getKey() or SBN.getPostTime() results in duplicate processing logic within the receiving app.

Engineering Solution Logic

  1. Mapping Consistency (ID Validation):
    Extract StatusBarNotification.getKey() as the primary unique index. This key is an immutable composite of pkg | id | tag | user.
  2. State Machine Defense (Content Validation):
    Implement a content-hashing mechanism for Notification.extras (specifically android.title and android.text). If the Key matches and the content hash is identical, the event must be classified as a "Silent Update" and discarded.
  3. Extreme Value Defense (Time-Windowing):
    To counter OEM-specific bursts of callbacks, implement a temporal filter based on getPostTime(). Subsequent events with the same Key within a specific threshold (e.g., <100ms) must be dropped.
  4. Explicit Scoping (Group Handling):
    Explicitly check SBN.isGroupSummary(). Depending on business requirements, you must filter out summary notifications to avoid double-counting the individual child notifications and their aggregate.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinggood first issueGood for newcomers

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions