feat: Android → Mac notification sync over BLE#72
Open
vegaglitch wants to merge 4 commits into
Open
Conversation
- Add NotificationListenerService to capture posted notifications - Add NotificationSettingsStore to persist the notification sync toggle - Extract app display name (QUERY_ALL_PACKAGES) and 64×64 PNG icon (base64-encoded) from each notification and include in the BLE payload - Add notification message type to MessageCodec and Session - Wire notification sync toggle into the settings UI (ClipRelayScreen, MainActivity, MainViewModel) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add notification message type to MessageCodec and Session - Fix protocol dispatch: add didReceiveNotification to SessionDelegate protocol declaration so conforming types are called (was extension-only, causing silent static-dispatch to the empty default) - Thread iconData (base64 PNG from Android) through Session → ConnectionController → AppDelegate → ReceiveNotificationManager - Attach icon as UNNotificationAttachment so it appears in the macOS notification banner Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Android: - NotificationRelayService: add icon extraction (renderIconBase64) so iconPng is actually included in the BLE payload; move TAG and settingsStore to companion/onCreate; remove empty onNotificationRemoved; reduce debug logging - MainActivity/MainViewModel: replace remember(Unit) for notificationListenerGranted with a ViewModel StateFlow refreshed in onResume, so the UI updates correctly after the user grants permission and returns to the app; import NotificationRelayService/ NotificationSettingsStore instead of using fully-qualified names inline macOS: - AppDelegate: restore SMAppService launch-at-login support that was accidentally removed when porting from NotiSyncMac - ReceiveNotificationManager: delete temp PNG file after UNNotification Attachment is created to avoid accumulating files in the temp directory Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…msung Samsung OneUI blocks NotificationListenerService callbacks for sideloaded APKs, so onNotificationPosted never fires. Instead, hook into the existing ClipboardAccessibilityService by adding TYPE_NOTIFICATION_STATE_CHANGED to its event mask and handling it independently of the auto-copy setting. Also add QUERY_ALL_PACKAGES permission so packageManager.getApplicationIcon() resolves icons for all installed apps on Android 11+. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Author
|
Note on dual notification capture paths The PR currently has two mechanisms for capturing Android notifications:
On non-Samsung devices, both paths will fire for the same notification. The Mac side won't show duplicates because A cleaner long-term fix would be one of:
Happy to implement whichever approach you prefer before merge. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This adds real-time notification mirroring from Android to Mac over the existing BLE L2CAP connection — no new pairing, no new infrastructure.
NotificationListenerServicecaptures posted notifications, resolves the human-readable app name, renders the app icon as a 64×64 PNG, and sends everything to Mac as an encrypted BLE notification message. A settings toggle in the main UI lets the user enable/disable the feature.UNUserNotificationwith the title, body, app-name subtitle, and icon attachment.didReceiveNotificationwas only declared in aSessionDelegateextension (static dispatch), so it silently hit the empty default. Moving it into the protocol declaration restores dynamic dispatch.What it looks like
Android notifications appear on Mac with:
Test plan
🤖 Generated with Claude Code