Interface: AndroidMediaSessionConfig
Defined in: packages/media-session/src/specs/media-session.nitro.ts:405
Android half of MediaSessionConfig. Ignored on iOS.
Properties
notificationChannelId
notificationChannelId: string;
Defined in: packages/media-session/src/specs/media-session.nitro.ts:407
Notification channel id. Created on API 26+ if it does not exist.
notificationChannelName
notificationChannelName: string;
Defined in: packages/media-session/src/specs/media-session.nitro.ts:409
User-visible channel name, shown in system notification settings.
notificationColor?
optional notificationColor?: number;
Defined in: packages/media-session/src/specs/media-session.nitro.ts:527
Notification accent colour, as an ARGB integer (0xFF1DB954).
Written straight onto Notification.color through a thin
MediaNotification.Provider decorator, because
DefaultMediaNotificationProvider.createNotification is final in media3
1.11.0 (javap on the shipped AAR) and its Builder exposes channel id,
channel name, notification id and small icon — but no colour. Decorating
the provider and setting the field on the notification it returns is the
only public lever, and it is applied after media3 has finished building, so
nothing media3 does can overwrite it.
Alpha is part of the value and is not optional: 0x1DB954 (alpha 0x00)
is transparent black on some OEM shades. Write the full 0xFFRRGGBB.
Whether the system uses it is the system's decision, and it changed twice: pre-Android-12 shades tint the small icon and action text with it, Android 12+ media notifications derive their own palette from the artwork and may ignore it entirely. It is therefore a hint, never a guarantee — the same status it has in every other library that exposes it.
Ignored on iOS: MPNowPlayingInfoCenter has no colour surface at all. The
lock screen's palette comes from the artwork, which is not ours to tint.
notificationIcon?
optional notificationIcon?: string;
Defined in: packages/media-session/src/specs/media-session.nitro.ts:420
Drawable resource name (e.g. 'ic_notification') resolved out of the
consumer app's resources at runtime — a library cannot reference an app's
generated R.
When absent or unresolvable, media3's own media3_notification_small_icon
is used. A small icon is never simply omitted: Notification throws
without one, and that throw would take the foreground-service start down
with it.
playbackResumption
playbackResumption: boolean;
Defined in: packages/media-session/src/specs/media-session.nitro.ts:502
Opt in to playback resumption after process death (Android only).
When true, the media3 service is allowed to come back from nothing: the
System UI resumption card, a Bluetooth reconnect or a headset play button
can start the service into a process with no JavaScript at all, and the
service will rebuild the session from a native mirror of the persisted
snapshot and then boot the React runtime behind it. See
RnMediaMediaSessionService.beginRevival and
RnMediaMediaSession.setResumptionSnapshot.
Three things are required and none of them is silently substituted:
withPersistence(...)— the mirror is written by it, and nothing else writes it. Without persistence there is nothing to resume.MediaService.init(...)must be reachable at JS module scope. A revived runtime loads the bundle but mounts no component, so aninitinside auseEffectnever runs and the revival is abandoned after a bounded wait (with a log saying exactly this).- The consuming app must declare media3's
MediaButtonReceiverin its manifest — that declaration is what makes media3 advertise resumption support to the System UI at all (MediaSessionLegacyStub.canResumePlaybackOnStartis literally "is there a broadcast receiver forACTION_MEDIA_BUTTON").
Default false: this path starts a foreground service from a process the
user did not open, so it stays opt-in until it has been proven on more
hardware than ours.
Why this lives under android and has no iOS twin
The cross-platform half of surviving process death is withPersistence
/ restorePersisted, which behave identically on both platforms. This flag
only names what Android can additionally do with that data: revive the
process by itself. iOS consumes the same record on the next manual
launch — the user opens the app and it is paused where they left it — and an
automatic iOS twin cannot exist, because on iOS a terminated app stays
terminated: force-quit is read as user intent and nothing may resurrect a
process for playback. That is Apple's policy, not a gap in this package.
See IosMediaSessionConfig for where an iOS twin would go if that
ever changes.
stopForegroundOnPause
stopForegroundOnPause: boolean;
Defined in: packages/media-session/src/specs/media-session.nitro.ts:428
true (audio_service's default) → stopForeground(STOP_FOREGROUND_DETACH)
when playback pauses: the notification survives but the service is demoted
to background and therefore killable. false keeps the service in the
foreground while paused, which is more robust but consumes an ongoing
notification slot.
stopForegroundTimeoutMs?
optional stopForegroundTimeoutMs?: number;
Defined in: packages/media-session/src/specs/media-session.nitro.ts:461
How long a paused service stays in the foreground before media3 demotes it, in milliseconds.
media3 1.11 does not demote on pause; it keeps the service foreground for a
"user engaged" grace period —
MediaSessionService.DEFAULT_FOREGROUND_SERVICE_TIMEOUT_MS, 10 minutes —
and only then applies stopForegroundOnPause. This maps 1:1 onto
@UnstableApi public final void MediaSessionService.setForegroundServiceTimeoutMs(long), called from the
service's onCreate (media3 1.11.0; verified by javap on the shipped AAR
and against
https://github.com/androidx/media/blob/1.11.0/libraries/session/src/main/java/androidx/media3/session/MediaSessionService.java#L643-L668).
Omit to keep media3's default. 0 demotes immediately on pause.
10 minutes is also the ceiling. media3 runs the value through
Util.constrainValue(v, 0, DEFAULT_FOREGROUND_SERVICE_TIMEOUT_MS), so a
larger number is silently clamped down rather than honoured. Values below
zero are rejected here before they can be clamped up to 0 in silence.
The trade-off runs both ways and neither end is free:
- Shorter — the process stops being protected sooner, so the OS may
reclaim it (and with it the JS runtime and the app's handler) minutes
after a pause. Better for battery/memory pressure; pair it with
withPersistenceso the session can be rebuilt. - Longer — a resume from the notification is far more likely to find the runtime still alive, at the cost of holding a foreground service (and its process) for that whole window.
Ignored on iOS: there is no service to demote.