Register now for Android Dev Summit 2019!

MediaSession

open class MediaSession : AutoCloseable
kotlin.Any
   ↳ 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 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 Builder or updatePlayer.

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 code MediaSession 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 SessionCallback#onFastForward
KeyEvent#KEYCODE_MEDIA_REWIND SessionCallback#onRewind

Summary

Nested classes

Builder for MediaSession.

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

Information of a controller.

abstract

Callback to be called for all incoming commands from MediaControllers.

Public methods

open Unit
broadcastCustomCommand(@NonNull command: SessionCommand, @Nullable args: Bundle?)

Broadcasts custom command to all connected controllers.

open Unit

open MutableList<MediaSession.ControllerInfo!>

Returns the list of connected controller.

open String

Gets the session ID

open SessionPlayer

Gets the underlying SessionPlayer.

open SessionToken

Returns the SessionToken for creating MediaController.

open ListenableFuture<SessionResult!>
sendCustomCommand(@NonNull controller: MediaSession.ControllerInfo, @NonNull command: SessionCommand, @Nullable args: Bundle?)

Send custom command to a specific controller.

open Unit
setAllowedCommands(@NonNull controller: MediaSession.ControllerInfo, @NonNull commands: SessionCommandGroup)

Sets the new allowed command group for the controller.

open ListenableFuture<SessionResult!>

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

open Unit
updatePlayer(@NonNull player: SessionPlayer)

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

Public methods

broadcastCustomCommand

open fun broadcastCustomCommand(@NonNull command: SessionCommand, @Nullable args: Bundle?): Unit

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 SessionCommand: optional argument

close

open fun close(): Unit

getConnectedControllers

@NonNull open fun getConnectedControllers(): MutableList<MediaSession.ControllerInfo!>

Returns the list of connected controller.

Return
MutableList<MediaSession.ControllerInfo!>: list of ControllerInfo

getId

@NonNull open fun getId(): String

Gets the session ID

Return
String:

getPlayer

@NonNull open fun getPlayer(): SessionPlayer

Gets the underlying SessionPlayer.

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

Return
SessionPlayer: player.

getToken

@NonNull open fun getToken(): SessionToken

Returns the SessionToken for creating MediaController.

sendCustomCommand

@NonNull open fun sendCustomCommand(@NonNull controller: MediaSession.ControllerInfo, @NonNull command: SessionCommand, @Nullable args: Bundle?): ListenableFuture<SessionResult!>

Send custom command to a specific controller.

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

Parameters
command MediaSession.ControllerInfo: a command
args MediaSession.ControllerInfo: optional argument

setAllowedCommands

open fun setAllowedCommands(@NonNull controller: MediaSession.ControllerInfo, @NonNull commands: SessionCommandGroup): Unit

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 MediaSession.ControllerInfo: new allowed commands

setCustomLayout

@NonNull open fun setCustomLayout(@NonNull controller: MediaSession.ControllerInfo, @NonNull layout: MutableList<MediaSession.CommandButton!>): ListenableFuture<SessionResult!>

Sets ordered list of 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 layout Layout 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 SessionCallback#onConnect(MediaSession, ControllerInfo).

Parameters
controller MediaSession.ControllerInfo: controller to specify layout.
layout MediaSession.ControllerInfo: ordered list of layout.

updatePlayer

open fun updatePlayer(@NonNull player: SessionPlayer): Unit

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