MediaController
open class MediaController : Closeable
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:
- Controller Lifecycle
- 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 theMediaSession
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 |
|
abstract |
Interface for listening to change in activeness of the |
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 |
open ListenableFuture<SessionResult!> |
adjustVolume(direction: Int, flags: Int) Requests that the connected |
open Unit |
close() Releases this object, and disconnects from the session. |
open ListenableFuture<SessionResult!> |
deselectTrack(@NonNull trackInfo: SessionPlayer.TrackInfo) Requests that the |
open ListenableFuture<SessionResult!> |
Requests that the |
open SessionCommandGroup? |
Gets the cached allowed commands from |
open Long |
Gets the position for how much has been buffered of the |
open Int |
Gets the current buffering state of the |
open SessionToken? |
Returns the |
open MediaItem? |
Gets the current media item of the |
open Int |
Gets the current item index in the playlist of the |
open Long |
Gets the playback position of the |
open Long |
Gets the duration of the current media item, or |
open Int |
Gets the next item index in the playlist of the |
open MediaController.PlaybackInfo? |
Get the current playback info for this session. |
open Float |
Gets the playback speed to be used by the of the |
open Int |
Gets the state of the |
open MutableList<MediaItem!>? |
Gets the playlist of the |
open MediaMetadata? |
Gets the playlist metadata of the |
open Int |
Gets the previous item index in the playlist of the |
open Int |
Gets the repeat mode of the |
open SessionPlayer.TrackInfo? |
getSelectedTrack(trackType: Int) Gets the currently selected track for the given track type of the |
open PendingIntent? |
Gets an intent for launching UI associated with this session if one exists. |
open Int |
Gets the shuffle mode of the |
open MutableList<SessionPlayer.TrackInfo!> |
Gets the full list of selected and unselected tracks that the media contains of the |
open VideoSize |
Gets the video size of the |
open Boolean |
Returns whether this class is connected to active |
open ListenableFuture<SessionResult!> |
movePlaylistItem(@IntRange(0) fromIndex: Int, @IntRange(0) toIndex: Int) Requests that the |
open ListenableFuture<SessionResult!> |
pause() Requests that the |
open ListenableFuture<SessionResult!> |
play() Requests that the |
open ListenableFuture<SessionResult!> |
prepare() Requests that the |
open ListenableFuture<SessionResult!> |
removePlaylistItem(@IntRange(0) index: Int) Requests that the |
open |