Skip to main content

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:

  1. withPersistence(...) — the mirror is written by it, and nothing else writes it. Without persistence there is nothing to resume.
  2. MediaService.init(...) must be reachable at JS module scope. A revived runtime loads the bundle but mounts no component, so an init inside a useEffect never runs and the revival is abandoned after a bounded wait (with a log saying exactly this).
  3. The consuming app must declare media3's MediaButtonReceiver in its manifest — that declaration is what makes media3 advertise resumption support to the System UI at all (MediaSessionLegacyStub.canResumePlaybackOnStart is literally "is there a broadcast receiver for ACTION_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 withPersistence so 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.