メディア コントローラはメディア セッションとやり取りして、メディアアプリの再生をクエリして制御します。Media3 では、MediaController
API が Player
インターフェースを実装します。メディア コントローラを使用するクライアント アプリの例を次に示します。
- Android システムのメディア コントロール
- Android Wear OS コンパニオン アプリ
- Android Auto と Automotive OS
- Google アシスタントなどの音声アシスタント
- Media Controller テストアプリ
メディア コントローラは、メディア アプリ内でも役立ちます。たとえば、プレーヤーとメディア セッションが UI の Activity
または Fragment
とは別の Service
にある場合などです。
MediaController
を作成
MediaController
を作成するには、まず対応する MediaSession
の SessionToken
を作成します。Activity
または Fragment
の onStart()
メソッドが適しています。
Kotlin
val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))
Java
SessionToken sessionToken = new SessionToken(context, new ComponentName(context, PlaybackService.class));
この SessionToken
を使用して MediaController
をビルドすると、コントローラが指定されたセッションに接続します。この処理は非同期で行われるため、結果をリッスンし、利用可能になったら使用する必要があります。
Kotlin
val controllerFuture = MediaController.Builder(context, sessionToken).buildAsync() controllerFuture.addListener({ // MediaController is available here with controllerFuture.get() }, MoreExecutors.directExecutor())
Java
ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(context, sessionToken).buildAsync(); controllerFuture.addListener(() -> { // MediaController is available here with controllerFuture.get() }, MoreExecutors.directExecutor());
MediaController
を使用
MediaController
は Player
インターフェースを実装しているため、インターフェースで定義されたコマンドを使用して、接続された MediaSession
の再生を制御できます。つまり、MediaController
で play()
を呼び出すと、接続された MediaSession
にコマンドが送信され、MediaSession
は基盤となる Player
にコマンドを委任します。
同様に、コントローラに Player.Listener
を追加して、Player
状態の変化をリッスンすることもできます。Player.Listener
の使用について詳しくは、プレーヤー イベント ガイドをご覧ください。MediaController.Listener
インターフェースは、接続された MediaSession
からのイベントと受信コマンドに追加のコールバックを定義します。たとえば、メディア セッションが使用可能なセッション コマンドを変更する場合の onAvailableSessionCommandsChanged()
や、コントローラがセッションから切断された場合の onDisconnected()
などです。
他のコンポーネントと同様に、Activity
や Fragment
の onStop()
メソッドなど、不要になったら MediaController
を解放してください。
Kotlin
MediaController.releaseFuture(controllerFuture)
Java
MediaController.releaseFuture(controllerFuture);
コントローラを解放しても、セッションに送信された保留中のコマンドはすべて配信され、これらのコマンドが処理されるか、タイムアウト時間が経過するかのいずれか早い時点で、セッション サービスからバインド解除されます。
MediaBrowser
を作成して使用する
MediaBrowser
は MediaController
が提供する機能の上に構築されており、メディアアプリの MediaLibraryService
が提供するメディア ライブラリのブラウジングも可能になります。
Kotlin
val browserFuture = MediaBrowser.Builder(context, sessionToken).buildAsync() browserFuture.addListener({ // MediaBrowser is available here with browserFuture.get() }, MoreExecutors.directExecutor())
Java
ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken).buildAsync(); browserFuture.addListener(() -> { // MediaBrowser is available here with browserFuture.get() }, MoreExecutors.directExecutor());
メディアアプリのコンテンツ ライブラリのブラウジングを開始するには、まず getLibraryRoot()
を使用してルートノードを取得します。
Kotlin
// Get the library root to start browsing the library tree. val rootFuture = mediaBrowser.getLibraryRoot(/* params= */ null) rootFuture.addListener({ // Root node MediaItem is available here with rootFuture.get().value }, MoreExecutors.directExecutor())
Java
// Get the library root to start browsing the library tree. ListenableFuture<LibraryResult<MediaItem>> rootFuture = mediaBrowser.getLibraryRoot(/* params= */ null); rootFuture.addListener(() -> { // Root node MediaItem is available here with rootFuture.get().value }, MoreExecutors.directExecutor());
次に、getChildren()
を使用してライブラリ内の MediaItem
の子孫を取得することで、メディア ライブラリを移動できます。たとえば、ルートノード MediaItem
の子ノードを取得するには、次のようにします。
Kotlin
// Get the library root to start browsing the library tree. val childrenFuture = mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Int.MAX_VALUE, null) childrenFuture.addListener({ // List of children MediaItem nodes is available here with // childrenFuture.get().value }, MoreExecutors.directExecutor())
Java
ListenableFuture<LibraryResult<ImmutableList<MediaItem>>> childrenFuture = mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Integer.MAX_VALUE, null); childrenFuture.addListener(() -> { // List of children MediaItem nodes is available here with // childrenFuture.get().value }, MoreExecutors.directExecutor());