A local Expo module listens to system media sessions (the only way Android exposes other apps' playback, gated by notification access; we never read notifications). It filters to known music apps, debounces and deduplicates changes, sends a heartbeat while playing, and delivers reports through WorkManager so they survive the app being closed. - One-screen onboarding that doubles as Google Play's prominent disclosure, opening straight to the app's toggle in Android settings - Only media notifications are pre-ticked on that settings screen - Device registration is single-flight (several screens react to the same permission change) and self-heals if the server revokes a token - Sign-out revokes the phone's token; resuming sharing re-sends the current track immediately - Pause controls in Settings and on the feed - Fix invisible tab icons and labels on Android - Keep Metro out of build output so it doesn't exhaust file watchers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
26 lines
1.1 KiB
XML
26 lines
1.1 KiB
XML
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
<uses-permission android:name="android.permission.INTERNET" />
|
|
|
|
<application>
|
|
<!--
|
|
Holding notification access is the only way Android lets an app see other apps'
|
|
media sessions. We never read notification contents; the service only uses its
|
|
binding to call MediaSessionManager.getActiveSessions().
|
|
-->
|
|
<service
|
|
android:name=".MediaListenerService"
|
|
android:label="@string/now_playing_listener_label"
|
|
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
|
|
android:exported="false">
|
|
<intent-filter>
|
|
<action android:name="android.service.notification.NotificationListenerService" />
|
|
</intent-filter>
|
|
<!-- Only media ("real-time") notifications are relevant, so the settings screen
|
|
doesn't pre-tick Conversations etc. We still never read notification contents. -->
|
|
<meta-data
|
|
android:name="android.service.notification.default_filter_types"
|
|
android:value="ongoing" />
|
|
</service>
|
|
</application>
|
|
</manifest>
|