Android 12 Developer Preview is here! Try it out, and give us your feedback!

MediaSessionService

abstract class MediaSessionService : Service
kotlin.Any
   ↳ android.content.Context
   ↳ android.content.ContextWrapper
   ↳ android.app.Service
   ↳ androidx.media2.session.MediaSessionService

Base class for media session services, which is the service containing MediaSession.

It's highly recommended for an app to use this if it wants to keep media playback in the background.

Here are the benefits of using MediaSessionService.

  • Another app can know that your app supports MediaSession even when your app isn't running.
  • Another app can start playback of your app even when your app isn't running.
For example, user's voice command can start playback of your app even when it's not running.

To extend this class, adding followings directly to your AndroidManifest.xml.

<service android:name="component_name_of_your_implementation" >
    <intent-filter>
      <action android:name="androidx.media2.session.MediaSessionService" />
    </intent-filter>
  </service>

You may also declare

android.media.browse.MediaBrowserService
for compatibility with android.support.v4.media.MediaBrowserCompat. This service can handle it automatically.

It's recommended for an app to have a single MediaSessionService declared in the manifest. Otherwise, your app might be shown twice in the list of the Auto/Wearable, or another app fails to pick the right session service when it wants to start the playback of this app. If you want to provide multiple sessions here, take a look at Supporting Multiple Sessions.

Topics covered here:

  1. Service Lifecycle
  2. Permissions
  3. Supporting Multiple Sessions

Service Lifecycle

Session service is a bound service. When a MediaController is created for the session service, the controller binds to the session service. onGetSession(ControllerInfo) would be called inside of the onBind(Intent).

After the binding, session's MediaSession.SessionCallback#onConnect(MediaSession, MediaSession.ControllerInfo) will be called to accept or reject connection request from a controller. If the connection is rejected, the controller will unbind. If it's accepted, the controller will be available to use and keep binding.

When playback is started for this session service, onUpdateNotification(MediaSession) is called for the playback's session and service would become a foreground service. It's needed to keep playback after the controller is destroyed. The session service becomes background service when all playbacks are stopped. Apps targeting API android.os.Build.VERSION_CODES#P or later must request the permission android.Manifest.permission#FOREGROUND_SERVICE in order to make the service foreground.

The service is destroyed when the all sessions are closed, or no media controller is binding to the session while the service is not running as a foreground service.

Permissions

Any app can bind to the session service with controller, but the controller can be used only if the session service accepted the connection request through MediaSession.SessionCallback#onConnect(MediaSession, MediaSession.ControllerInfo).

Supporting Multiple Sessions

Generally speaking, multiple sessions aren't necessary for most media apps. One exception is if your app can play multiple media content at the same time, but only for the playback of video-only media or remote playback, since audio focus policy recommends not playing multiple audio content at the same time. Also keep in mind that multiple media sessions would make Android Auto and Bluetooth device with display to show your apps multiple times, because they list up media sessions, not media apps.

However, if you're capable of handling multiple playback and want to keep their sessions while the app is in the background, create multiple sessions and add to this service with addSession(MediaSession).

Note that MediaController can be created with SessionToken for connecting any session in this service. In that case, onGetSession(ControllerInfo) will be called to know which session to handle incoming connection request. Pick the best session among added sessions, or create new one and return from the onGetSession(ControllerInfo).

Summary

Nested classes
open

Returned by onUpdateNotification(MediaSession) for making session service foreground service to keep playback running in the background.

Constants
static String

The Intent that must be declared as handled by the service.

Public constructors

Public methods
Unit
addSession(@NonNull session: MediaSession)

Adds a session to this service.

MutableList<MediaSession!>

Gets the list of MediaSessions that you've added to this service via addSession or onGetSession(ControllerInfo).

open IBinder?
onBind(@NonNull intent: Intent)

Default implementation for MediaSessionService to handle incoming binding request.

open Unit

Called by the system when the service is first created.

open Unit

Called by the system to notify that it is no longer used and is being removed.

abstract MediaSession?
onGetSession(@NonNull controllerInfo: MediaSession.ControllerInfo)

Called when a MediaController is created with the this service's SessionToken.

open Int
onStartCommand(intent: Intent!, flags: Int, startId: Int)

open MediaSessionService.MediaNotification?

Called when notification UI needs update.

Unit
removeSession(@NonNull session: MediaSession)

Removes a session from this service.

Constants

SERVICE_INTERFACE

static val SERVICE_INTERFACE: String

The Intent that must be declared as handled by the service.

Value: "androidx.media2.session.MediaSessionService"

Public constructors

<init>

MediaSessionService()

Public methods

addSession

fun addSession(@NonNull session: MediaSession): Unit

Adds a session to this service. This is not necessary for most media apps. See Supporting Multiple Sessions for detail.

Added session will be removed automatically when it's closed, or removed when removeSession is called.

Parameters
session MediaSession: a session to be added.

getSessions

@NonNull fun getSessions(): MutableList<MediaSession!