6 月 3 日の「#Android11: The Beta Launch Show」にぜひご参加ください。

MediaController

open class MediaController : AutoCloseable
kotlin.Any
   ↳ androidx.media2.session.MediaController

Allows an app to interact with an active or a MediaSessionService which would provide . Media buttons and other commands can be sent to the session.

MediaController objects are thread-safe.

Topics covered here:

  1. Controller Lifecycle
  2. Controlling the MediaSession in the same process

Controller Lifecycle

When a controller is created with the SessionToken for a MediaSession (i.e. session token type is SessionToken#TYPE_SESSION), the controller will connect to the specific session.

When a controller is created with the SessionToken for a MediaSessionService (i.e. session token type is SessionToken#TYPE_SESSION_SERVICE or SessionToken#TYPE_LIBRARY_SERVICE), the controller binds to the service for connecting to a MediaSession in it. MediaSessionService will provide a session to connect.

When a controller connects to a session, MediaSession.SessionCallback#onConnect(MediaSession, MediaSession.ControllerInfo) will be called to either accept or reject the connection. Wait ControllerCallback#onConnected(MediaController, SessionCommandGroup) or ControllerCallback#onDisconnected(MediaController) for the result.

When the connected session is closed, the controller will receive ControllerCallback#onDisconnected(MediaController).

When you're done, use close() to clean up resources. This also helps session service to be destroyed when there's no controller associated with it.

Controlling the MediaSession in the same process

When you control the MediaSession and its SessionPlayer, it's recommended to use them directly rather than creating MediaController. However, if you need to use MediaController in the same process, be careful not to block session callback executor's thread. Here's an example code that would never return due to the thread issue.

<code>// Code runs on the main thread.
  MediaSession session = new MediaSession.Builder(context, player)
     .setSessionCallback(sessionCallback, Context.getMainExecutor(context)).build();
  MediaController controller = new MediaController.Builder(context)
     .setSessionToken(session.getToken())
     .setControllerCallback(Context.getMainExecutor(context), controllerCallback)
     .build();
 
  // This will hang and never return.
  controller.play().get();</code>
When a session gets a command from a controller, the session's MediaSession.SessionCallback#onCommandRequest would be executed on the session's callback executor to decide whether to ignore or handle the incoming command. To do so, the session's callback executor shouldn't be blocked to handle the incoming calls. However, if you call ListenableFuture#get on the thread for the session callback executor, then your call wouldn't be executed and never return.

To avoid such issue, don't block the session callback executor's thread. Creating a dedicated thread for the session callback executor would be helpful. See Executors#newSingleThreadExecutor for creating a new thread.

Summary

Nested classes

Builder for MediaController.

abstract

Interface for listening to change in activeness of the MediaSession.

Holds information about the way volume is handled for this session.

Public methods

open ListenableFuture<SessionResult!>
addPlaylistItem(@IntRange(0) index: Int, @NonNull mediaId: String)

Requests that the SessionPlayer associated with the connected MediaSession adds the media item to the playlist at the index with the media ID.

open ListenableFuture<SessionResult!>
adjustVolume(direction: Int, flags: Int)

Requests that the connected MediaSession adjusts the volume of the output that is playing on.

open Unit

Releases this object, and disconnects from the session.

open ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession to fast forward playback.

open Long

Gets the lastly cached buffered position from the session when ControllerCallback#onBufferingStateChanged(MediaController, MediaItem, int) is called.

open Int

Gets the current buffering state of the SessionPlayer associated with the connected MediaSession.

open SessionToken?

Returns the SessionToken of the connected session.

open MediaItem?

Gets the lastly cached current item from ControllerCallback#onCurrentMediaItemChanged(MediaController, MediaItem).

open Int

Gets the current item index in the playlist.

open Long

Gets the current playback position.

open Long

Gets the duration of the current media item, or SessionPlayer#UNKNOWN_TIME if unknown or not connected.

open Int

Gets the next item index in the playlist.

open MediaController.PlaybackInfo?

Get the current playback info for this session.

open Float

Gets the lastly cached playback speed from ControllerCallback#onPlaybackSpeedChanged(MediaController, float).

open Int

Gets the lastly cached player state from ControllerCallback#onPlayerStateChanged(MediaController, int).

open MutableList<MediaItem!>?

Returns the cached playlist from ControllerCallback#onPlaylistChanged.

open MediaMetadata?

Gets the lastly cached playlist metadata either from ControllerCallback#onPlaylistMetadataChanged or ControllerCallback#onPlaylistChanged.

open Int

Gets the previous item index in the playlist.

open Int

Gets the cached repeat mode from the ControllerCallback#onRepeatModeChanged.

open PendingIntent?

Gets an intent for launching UI associated with this session if one exists.

open Int

Gets the cached shuffle mode from the ControllerCallback#onShuffleModeChanged.

open Boolean

Returns whether this class is connected to active MediaSession or not.

open ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession pauses playback.

open ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession starts or resumes playback.

open ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession prepares the media items for playback.

open ListenableFuture<SessionResult!>
removePlaylistItem(@IntRange(0) index: Int)

Requests that the SessionPlayer associated with the connected MediaSession removes the media item at index in the playlist.

open ListenableFuture<SessionResult!>
replacePlaylistItem(@IntRange(0) index: Int, @NonNull mediaId: String)

Requests that the SessionPlayer associated with the connected MediaSession replaces the media item at index in the playlist with the media ID.

open ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession to rewind playback.

open ListenableFuture<SessionResult!>
seekTo(pos: Long)

Requests that the SessionPlayer associated with the connected MediaSession moves to a new location in the media stream.

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

Sends a custom command to the session

open ListenableFuture<SessionResult!>
setMediaItem(@NonNull mediaId: String)

Requests that the SessionPlayer associated with the connected MediaSession sets a MediaItem for playback with the media ID.

open ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession sets the playback speed.

open ListenableFuture<SessionResult!>
setPlaylist(@NonNull list: MutableList<String!>, @Nullable metadata: MediaMetadata?)

Requests that the SessionPlayer associated with the connected MediaSession sets the playlist with the list of media IDs.

open ListenableFuture<SessionResult!>
setRating(@NonNull mediaId: String, @NonNull rating: Rating)

Requests that the connected MediaSession rates the media.

open ListenableFuture<SessionResult!>
setRepeatMode(repeatMode: Int)

Requests that the SessionPlayer associated with the connected MediaSession sets the repeat mode.

open ListenableFuture<SessionResult!>
setShuffleMode(shuffleMode: Int)

Requests that the SessionPlayer associated with the connected MediaSession sets the shuffle mode.

open ListenableFuture<SessionResult!>
setVolumeTo(value: Int, flags: Int)

Requests that the connected MediaSession sets the volume of the output that is playing on.

open ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession skips forward within the current media item.

open ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession skips backward within the current media item.

open ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession skips to the next item in the playlist.

open ListenableFuture<SessionResult!>
skipToPlaylistItem(@IntRange(0) index: Int)

Requests that the SessionPlayer associated with the connected MediaSession skips to the item in the playlist at the index.

open ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession skips to the previous item in the playlist.

open ListenableFuture<SessionResult!>
updatePlaylistMetadata(@Nullable metadata: MediaMetadata?)

Requests that the SessionPlayer associated with the connected MediaSession updates the playlist metadata

Public methods

addPlaylistItem

@NonNull open fun addPlaylistItem(
    @IntRange(0) index: Int,
    @NonNull mediaId: String
): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession adds the media item to the playlist at the index with the media ID. Index equals to or greater than the current playlist size (e.g. Integer#MAX_VALUE) will add the item at the end of the playlist.

This will not change the currently playing media item. If index is less than or equal to the current index of the playlist, the current index of the playlist will be incremented correspondingly.

Parameters
index Int: the index you want to add
mediaId String: the non-empty media id of the new item

adjustVolume

@NonNull open fun adjustVolume(
    direction: Int,
    flags: Int
): ListenableFuture<SessionResult!>

Requests that the connected MediaSession adjusts the volume of the output that is playing on. The direction must be one of AudioManager#ADJUST_LOWER, AudioManager#ADJUST_RAISE, or AudioManager#ADJUST_SAME.

The command will be ignored if the session does not support VolumeProviderCompat#VOLUME_CONTROL_RELATIVE or VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE.

If the session is local playback, this changes the device's volume with the stream that session's player is using. Flags will be specified for the AudioManager.

If the session is remote player (i.e. session has set volume provider), its volume provider will receive this request instead.

Parameters
direction Int: The direction to adjust the volume in.
flags Int: flags from AudioManager to include with the volume request for local playback

close

open fun close(): Unit

Releases this object, and disconnects from the session. After this, callbacks wouldn't be received.

fastForward

@NonNull open fun fastForward(): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession to fast forward playback.

The implementation may be different depending on the players. For example, it can be implemented by seeking forward once, series of seeking forward, or increasing playback speed. If you need full control, then use seekTo or setPlaybackSpeed directly.

getBufferedPosition

open fun getBufferedPosition(): Long

Gets the lastly cached buffered position from the session when ControllerCallback#onBufferingStateChanged(MediaController, MediaItem, int) is called.

Return
Long buffering position in millis, or SessionPlayer#UNKNOWN_TIME if unknown or not connected

getBufferingState

open fun getBufferingState(): Int

Gets the current buffering state of the SessionPlayer associated with the connected MediaSession. During buffering, see getBufferedPosition() for the quantifying the amount already buffered.

Return
Int the buffering state, or SessionPlayer#BUFFERING_STATE_UNKNOWN if unknown or not connected

getConnectedToken

@Nullable open fun getConnectedToken(): SessionToken?

Returns the SessionToken of the connected session. If it is not connected yet, it returns null.

This may differ from the SessionToken from the constructor. For example, if the controller is created with the token for MediaSessionService, this would return token for the MediaSession in the service.

Return
SessionToken? SessionToken of the connected session, or null if not connected

getCurrentMediaItem

@Nullable open fun getCurrentMediaItem(): MediaItem?

Gets the lastly cached current item from ControllerCallback#onCurrentMediaItemChanged(MediaController, MediaItem).

Return
MediaItem? the currently playing item, or null if unknown or not connected

getCurrentMediaItemIndex

open fun getCurrentMediaItemIndex(): Int

Gets the current item index in the playlist. The returned value can be outdated after ControllerCallback#onCurrentMediaItemChanged(MediaController, MediaItem) or ControllerCallback#onPlaylistChanged(MediaController, List, MediaMetadata) is called.

Return
Int the index of current item in playlist, or -1 if current media item does not exist or playlist hasn't been set.

getCurrentPosition

open fun getCurrentPosition(): Long

Gets the current playback position.

This returns the calculated value of the position, based on the difference between the update time and current time.

Return
Long the current playback position in ms, or SessionPlayer#UNKNOWN_TIME if unknown or not connected

getDuration

open fun getDuration(): Long

Gets the duration of the current media item, or SessionPlayer#UNKNOWN_TIME if unknown or not connected.

Return
Long the duration in ms, or SessionPlayer#UNKNOWN_TIME

getNextMediaItemIndex

open fun getNextMediaItemIndex(): Int

Gets the next item index in the playlist. The returned value can be outdated after ControllerCallback#onCurrentMediaItemChanged(MediaController, MediaItem) or ControllerCallback#onPlaylistChanged(MediaController, List, MediaMetadata) is called.

Interoperability: When connected to android.support.v4.media.session.MediaSessionCompat, this will always return -1.

Return
Int the index of next item in playlist, or -1 if next media item does not exist or playlist hasn't been set.

getPlaybackInfo

@Nullable open fun getPlaybackInfo(): MediaController.PlaybackInfo?

Get the current playback info for this session. If it is not connected yet, it returns null.

Return
MediaController.PlaybackInfo? the current playback info or null

getPlaybackSpeed

open fun getPlaybackSpeed(): Float

Gets the lastly cached playback speed from ControllerCallback#onPlaybackSpeedChanged(MediaController, float).

Return
Float speed the lastly cached playback speed, or 0f if unknown or not connected

getPlayerState

open fun getPlayerState(): Int

Gets the lastly cached player state from ControllerCallback#onPlayerStateChanged(MediaController, int). If it is not connected yet, it returns SessionPlayer#PLAYER_STATE_IDLE.

Return
Int player state

getPlaylist

@Nullable open fun getPlaylist(): MutableList<MediaItem!>?

Returns the cached playlist from ControllerCallback#onPlaylistChanged. Can be null if the playlist hasn't been set or it's reset by setMediaItem.

This list may differ from the list that was specified with setPlaylist(List, MediaMetadata) depending on the SessionPlayer implementation. Use media items returned here for other playlist agent APIs such as SessionPlayer#skipToPlaylistItem.

Return
MutableList<MediaItem!>? playlist, or null if the playlist hasn't been set, controller isn't connected, or it doesn't have enough permission

getPlaylistMetadata

@Nullable open fun getPlaylistMetadata(): MediaMetadata?

Gets the lastly cached playlist metadata either from ControllerCallback#onPlaylistMetadataChanged or ControllerCallback#onPlaylistChanged.

Return
MediaMetadata? metadata of the playlist, or null if none is set or the controller is not connected

getPreviousMediaItemIndex

open fun getPreviousMediaItemIndex(): Int

Gets the previous item index in the playlist. The returned value can be outdated after ControllerCallback#onCurrentMediaItemChanged(MediaController, MediaItem) or ControllerCallback#onPlaylistChanged(MediaController, List, MediaMetadata) is called.

Interoperability: When connected to android.support.v4.media.session.MediaSessionCompat, this will always return -1.

Return
Int the index of previous item in playlist, or -1 if previous media item does not exist or playlist hasn't been set.

getRepeatMode

open fun getRepeatMode(): Int

Gets the cached repeat mode from the ControllerCallback#onRepeatModeChanged. If it is not connected yet, it returns SessionPlayer#REPEAT_MODE_NONE.

Return
Int repeat mode

getSessionActivity

@Nullable open fun getSessionActivity(): PendingIntent?

Gets an intent for launching UI associated with this session if one exists. If it is not connected yet, it returns null.

Return
PendingIntent? a PendingIntent to launch UI or null

getShuffleMode

open fun getShuffleMode(): Int

Gets the cached shuffle mode from the ControllerCallback#onShuffleModeChanged. If it is not connected yet, it returns SessionPlayer#SHUFFLE_MODE_NONE.

Return
Int The shuffle mode

isConnected

open fun isConnected(): Boolean

Returns whether this class is connected to active MediaSession or not.

pause

@NonNull open fun pause(): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession pauses playback.

This would transfer the player state from SessionPlayer#PLAYER_STATE_PLAYING to SessionPlayer#PLAYER_STATE_PAUSED.

play

@NonNull open fun play(): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession starts or resumes playback.

If the player state is SessionPlayer#PLAYER_STATE_IDLE, the session would also call SessionPlayer#prepare and then SessionPlayer#play to start playback. If you want to have finer grained control of the playback start, call prepare manually before this. Calling prepare in advance would help this method to start playback faster and also help to take audio focus at the last moment.

See Also

prepare

@NonNull open fun prepare(): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession prepares the media items for playback.

This would transfer the player state from SessionPlayer#PLAYER_STATE_IDLE to SessionPlayer#PLAYER_STATE_PAUSED.

Playback can be started without this. But this provides finer grained control of playback start. See play for details.

See Also

removePlaylistItem

@NonNull open fun removePlaylistItem(@IntRange(0) index: Int): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession removes the media item at index in the playlist.

If the item is the currently playing item of the playlist, current playback will be stopped and playback moves to next source in the list.

Parameters
index Int: the media item you want to add

replacePlaylistItem

@NonNull open fun replacePlaylistItem(
    @IntRange(0) index: Int,
    @NonNull mediaId: String
): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession replaces the media item at index in the playlist with the media ID.

Parameters
index Int: the index of the item to replace
mediaId String: the non-empty media id of the new item

rewind

@NonNull open fun rewind(): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession to rewind playback.

The implementation may be different depending on the players. For example, it can be implemented by seeking backward once, series of seeking backward, or decreasing playback speed. If you need full control, then use seekTo or setPlaybackSpeed directly.

seekTo

@NonNull open fun seekTo(pos: Long): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession moves to a new location in the media stream.

Parameters
pos Long: position to move to, in milliseconds

sendCustomCommand

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

Sends a custom command to the session

Interoperability: When connected to android.support.v4.media.session.MediaSessionCompat, SessionResult#getResultCode() will return the custom result code from the ResultReceiver#onReceiveResult(int, Bundle) instead of the standard result codes defined in the SessionResult.

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

Parameters
command SessionCommand: custom command
args Bundle?: optional argument

setMediaItem

@NonNull open fun setMediaItem(@NonNull mediaId: String): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession sets a MediaItem for playback with the media ID. Use this or setPlaylist to specify which items to play. If you want to change current item in the playlist, use one of skipToPlaylistItem, skipToNextPlaylistItem, or skipToPreviousPlaylistItem instead of this method.

The ControllerCallback#onPlaylistChanged and ControllerCallback#onCurrentMediaItemChanged would be called when it's completed. The current item would be the item given here.

Parameters
mediaId String: the non-empty media id of the item to play

setPlaybackSpeed

@NonNull open fun setPlaybackSpeed(speed: Float): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession sets the playback speed. A value of 1.0f is the default playback value, and a negative value indicates reverse playback. 0.0f is not allowed.

Exceptions
IllegalArgumentException if the speed is equal to zero.

setPlaylist

@NonNull open fun setPlaylist(
    @NonNull list: MutableList<String!>,
    @Nullable metadata: MediaMetadata?
): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession sets the playlist with the list of media IDs. Use this or setMediaItem to specify which items to play.

All media IDs in the list shouldn't be an empty string.

The ControllerCallback#onPlaylistChanged and ControllerCallback#onCurrentMediaItemChanged would be called when it's completed. The current item would be the first item in the playlist.

Parameters
list MutableList<String!>: list of media id. Shouldn't contain an empty id.
metadata MediaMetadata?: metadata of the playlist
Exceptions
IllegalArgumentException if the list is null or contains any empty string.

setRating

@NonNull open fun setRating(
    @NonNull mediaId: String,
    @NonNull rating: Rating
): ListenableFuture<SessionResult!>

Requests that the connected MediaSession rates the media. This will cause the rating to be set for the current user. The rating style must follow the user rating style from the session.You can get the rating style from the session through the MediaMetadata#getRating(String) with the key MediaMetadata#METADATA_KEY_USER_RATING.

If the user rating was null, the media item does not accept setting user rating.

Parameters
mediaId String: the non-empty media id
rating Rating: the rating to set

setRepeatMode

@NonNull open fun setRepeatMode(repeatMode: Int): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession sets the repeat mode.

Parameters
repeatMode Int: repeat mode

setShuffleMode

@NonNull open fun setShuffleMode(shuffleMode: Int): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession sets the shuffle mode.

Parameters
shuffleMode Int: The shuffle mode

setVolumeTo

@NonNull open fun setVolumeTo(
    value: Int,
    flags: Int
): ListenableFuture<SessionResult!>

Requests that the connected MediaSession sets the volume of the output that is playing on. The command will be ignored if it does not support VolumeProviderCompat#VOLUME_CONTROL_ABSOLUTE.

If the session is local playback, this changes the device's volume with the stream that session's player is using. Flags will be specified for the AudioManager.

If the session is remote player (i.e. session has set volume provider), its volume provider will receive this request instead.

Parameters
value Int: the value to set it to, between 0 and the reported max
flags Int: flags from AudioManager to include with the volume request for local playback

skipBackward

@NonNull open fun skipBackward(): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession skips forward within the current media item.

The implementation may be different depending on the players. For example, it can be implemented by seeking backward once with the fixed amount of seconds, or seeking backward to the nearest bookmark. If you need full control, then use seekTo directly.

skipForward

@NonNull open fun skipForward(): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession skips backward within the current media item.

The implementation may be different depending on the players. For example, it can be implemented by seeking forward once with the fixed amount of seconds, or seeking forward to the nearest bookmark. If you need full control, then use seekTo directly. *

skipToNextPlaylistItem

@NonNull open fun skipToNextPlaylistItem(): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession skips to the next item in the playlist.

This calls SessionPlayer#skipToNextPlaylistItem().

skipToPlaylistItem

@NonNull open fun skipToPlaylistItem(@IntRange(0) index: Int): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession skips to the item in the playlist at the index.

This calls SessionPlayer#skipToPlaylistItem(int).

Parameters
index Int: The index of the item you want to play in the playlist

skipToPreviousPlaylistItem

@NonNull open fun skipToPreviousPlaylistItem(): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession skips to the previous item in the playlist.

This calls SessionPlayer#skipToPreviousPlaylistItem().

updatePlaylistMetadata

@NonNull open fun updatePlaylistMetadata(@Nullable metadata: MediaMetadata?): ListenableFuture<SessionResult!>

Requests that the SessionPlayer associated with the connected MediaSession updates the playlist metadata

Parameters
metadata MediaMetadata?: metadata of the playlist