Register now for Android Dev Summit 2019!

MediaSession

public class MediaSession
extends Object implements AutoCloseable

java.lang.Object
   ↳ androidx.media2.session.MediaSession


Allows a media app to expose its transport controls and playback information in a process to other processes including the Android framework and other apps. Common use cases are as follows.

  • Bluetooth/wired headset key events support
  • Android Auto/Wearable support
  • Separating UI process and playback process

A MediaSession should be created when an app wants to publish media playback information or handle media keys. In general an app only needs one session for all playback, though multiple sessions can be created to provide finer grain controls of media.

If you want to support background playback, MediaSessionService is preferred instead. With it, your playback can be revived even after playback is finished. See MediaSessionService for details.

Topic covered here:

  1. Session Lifecycle
  2. Audio focus and noisy intent
  3. Thread
  4. Media key events mapping

Session Lifecycle

A session can be obtained by MediaSession.Builder. The owner of the session may pass its session token to other processes to allow them to create a MediaController to interact with the session.

When a session receive transport control commands, the session sends the commands directly to the the underlying media player set by MediaSession.Builder or updatePlayer(SessionPlayer).

When an app is finished performing playback it must call close() to clean up the session and notify any controllers. The app is responsible for closing the underlying player after closing the session. is closed.

Thread

MediaSession objects are thread safe, but should be used on the thread on the looper.

Media key events mapping

Here's the table of per key event.

Key codeMediaSession API
KeyEvent.KEYCODE_MEDIA_PLAY SessionPlayer.play()
KeyEvent.KEYCODE_MEDIA_PAUSE SessionPlayer.pause()
KeyEvent.KEYCODE_MEDIA_NEXT SessionPlayer.skipToNextPlaylistItem()
KeyEvent.KEYCODE_MEDIA_PREVIOUS SessionPlayer.skipToPreviousPlaylistItem()
KeyEvent.KEYCODE_MEDIA_STOP SessionPlayer.pause() and then SessionPlayer.seekTo(long) with 0
KeyEvent.KEYCODE_MEDIA_FAST_FORWARD MediaSession.SessionCallback.onFastForward(MediaSession, MediaSession.ControllerInfo)
KeyEvent.KEYCODE_MEDIA_REWIND MediaSession.SessionCallback.onRewind(MediaSession, MediaSession.ControllerInfo)

Summary

Nested classes

class MediaSession.Builder

Builder for MediaSession

class MediaSession.CommandButton

Button for a SessionCommand that will be shown by the controller. 

class MediaSession.ControllerInfo

Information of a controller. 

class MediaSession.SessionCallback

Callback to be called for all incoming commands from MediaControllers. 

Public methods

void broadcastCustomCommand(SessionCommand command, Bundle args)

Broadcasts custom command to all connected controllers.

void close()
List<MediaSession.ControllerInfo> getConnectedControllers()

Returns the list of connected controller.

String getId()

Gets the session ID

SessionPlayer getPlayer()

Gets the underlying SessionPlayer.

SessionToken getToken()

Returns the SessionToken for creating MediaController.

ListenableFuture<SessionResult> sendCustomCommand(MediaSession.ControllerInfo controller, SessionCommand command, Bundle args)

Send custom command to a specific controller.

void setAllowedCommands(MediaSession.ControllerInfo controller, SessionCommandGroup commands)

Sets the new allowed command group for the controller.

ListenableFuture<SessionResult> setCustomLayout(MediaSession.ControllerInfo controller, List<MediaSession.CommandButton> layout)

Sets ordered list of MediaSession.CommandButton for controllers to build UI with it.

void updatePlayer(SessionPlayer player)

Updates the underlying SessionPlayer for this session to dispatch incoming event to.

Inherited methods

Public methods

broadcastCustomCommand

public void broadcastCustomCommand (SessionCommand command, 
                Bundle args)

Broadcasts custom command to all connected controllers.

This is synchronous call and doesn't wait for result from the controller. Use sendCustomCommand(ControllerInfo, SessionCommand, Bundle) for getting the result.

A command is not accepted if it is not a custom command.

Parameters
command SessionCommand: a command

args Bundle: optional argument

close

public void close ()

getConnectedControllers

public List<MediaSession.ControllerInfo> getConnectedControllers ()

Returns the list of connected controller.

Returns
List<MediaSession.ControllerInfo> list of MediaSession.ControllerInfo

getId

public String getId ()

Gets the session ID

Returns
String

getPlayer

public SessionPlayer getPlayer ()

Gets the underlying SessionPlayer.

When the session is closed, it returns the lastly set player.

Returns
SessionPlayer player.

getToken

public SessionToken getToken ()

Returns the SessionToken for creating MediaController.

Returns
SessionToken

sendCustomCommand

public ListenableFuture<SessionResult> sendCustomCommand (MediaSession.ControllerInfo controller, 
                SessionCommand command, 
                Bundle args)

Send custom command to a specific controller.

A command is not accepted if it is not a custom command.

Parameters
controller MediaSession.ControllerInfo

command SessionCommand: a command

args Bundle: optional argument

Returns
ListenableFuture<SessionResult>

setAllowedCommands

public void setAllowedCommands (MediaSession.ControllerInfo controller, 
                SessionCommandGroup commands)

Sets the new allowed command group for the controller.

This is synchronous call. Changes in the allowed commands take effect immediately regardless of the controller notified about the change through #onAllowedCommandsChanged(MediaController, SessionCommandGroup)

Parameters
controller MediaSession.ControllerInfo: controller to change allowed commands

commands SessionCommandGroup: new allowed commands

setCustomLayout

public ListenableFuture<SessionResult> setCustomLayout (MediaSession.ControllerInfo controller, 
                List<MediaSession.CommandButton> layout)

Sets ordered list of MediaSession.CommandButton for controllers to build UI with it.

It's up to controller's decision how to represent the layout in its own UI. Here are some examples.

Note: layout[i] means a CommandButton at index i in the given list

Controller UX layoutLayout example
Row with 3 icons layout[1] layout[0] layout[2]
Row with 5 icons layout[3] layout[1] layout[0] layout[2] layout[4]
Row with 5 icons and an overflow icon, and another expandable row with 5 extra icons layout[3] layout[1] layout[0] layout[2] layout[4]
layout[3] layout[1] layout[0] layout[2] layout[4]

This API can be called in the MediaSession.SessionCallback.onConnect(MediaSession, ControllerInfo).

Parameters
controller MediaSession.ControllerInfo: controller to specify layout.

layout List: ordered list of layout.

Returns
ListenableFuture<SessionResult>

updatePlayer

public void updatePlayer (SessionPlayer player)

Updates the underlying SessionPlayer for this session to dispatch incoming event to.

Parameters
player SessionPlayer: a player that handles actual media playback in your app