メディアアプリには、階層で編成されたメディア アイテムのコレクションが含まれていることがよくあります。たとえば、アルバム内の曲やプレイリスト内のテレビ エピソードなどです。このメディア アイテムの階層はメディア ライブラリと呼ばれます。
MediaLibraryService
は、メディア ライブラリの提供とアクセスを行う標準化された API を提供します。これは、メディアアプリに Android Auto のサポートを追加する場合などに役立ちます。この場合、メディア ライブラリにドライバー向けの独自の UI が提供されます。
MediaLibraryService
をビルドする
MediaLibraryService
の実装は MediaSessionService
の実装と似ていますが、onGetSession()
メソッドでは MediaSession
ではなく MediaLibrarySession
を返す必要があります。
Kotlin
class PlaybackService : MediaLibraryService() { var mediaLibrarySession: MediaLibrarySession? = null var callback: MediaLibrarySession.Callback = object : MediaLibrarySession.Callback {...} // If desired, validate the controller before returning the media library session override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaLibrarySession? = mediaLibrarySession // Create your player and media library session in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaLibrarySession = MediaLibrarySession.Builder(this, player, callback).build() } // Remember to release the player and media library session in onDestroy override fun onDestroy() { mediaLibrarySession?.run { player.release() release() mediaLibrarySession = null } super.onDestroy() } }
Java
class PlaybackService extends MediaLibraryService { MediaLibrarySession mediaLibrarySession = null; MediaLibrarySession.Callback callback = new MediaLibrarySession.Callback() {...}; @Override public MediaLibrarySession onGetSession(MediaSession.ControllerInfo controllerInfo) { // If desired, validate the controller before returning the media library session return mediaLibrarySession; } // Create your player and media library session in the onCreate lifecycle event @Override public void onCreate() { super.onCreate(); ExoPlayer player = new ExoPlayer.Builder(this).build(); mediaLibrarySession = new MediaLibrarySession.Builder(this, player, callback).build(); } // Remember to release the player and media library session in onDestroy @Override public void onDestroy() { if (mediaLibrarySession != null) { mediaLibrarySession.getPlayer().release(); mediaLibrarySession.release(); mediaLibrarySession = null; } super.onDestroy(); } }
マニフェスト ファイルで Service
と必要な権限も宣言してください。
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- For targetSdk 34+ -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
MediaLibrarySession
を使用
MediaLibraryService
API では、メディア ライブラリがツリー形式で構成され、単一のルートノードと、再生またはブラウジングが可能な子ノードがあることを前提としています。
MediaLibrarySession
は MediaSession
API を拡張して、コンテンツ ブラウジング API を追加します。MediaSession
コールバックと比較して、MediaLibrarySession
コールバックには次のようなメソッドが追加されています。
onGetLibraryRoot()
- クライアントがコンテンツ ツリーのルートMediaItem
をリクエストする場合onGetChildren()
クライアントがコンテンツ ツリー内のMediaItem
の子孫をリクエストする場合onGetSearchResult()
: クライアントが特定のクエリに対してコンテンツ ツリーから検索結果をリクエストする場合
関連するコールバック メソッドには、クライアント アプリが関心を持っているコンテンツ ツリーのタイプに関する追加のシグナルを含む LibraryParams
オブジェクトが含まれます。
メディア アイテムのコマンドボタン
セッション アプリは、MediaMetadata
で MediaItem
でサポートされているコマンドボタンを宣言できます。これにより、コントローラが表示できるメディア アイテムに 1 つ以上の CommandButton
エントリを割り当て、アイテムのカスタム コマンドをセッションに簡単に送信できます。
セッション側でコマンドボタンを設定する
セッションをビルドするときに、セッションアプリは、セッションがカスタム コマンドとして処理できるコマンドボタンのセットを宣言します。
Kotlin
val allCommandButtons = listOf( CommandButton.Builder(CommandButton.ICON_PLAYLIST_ADD) .setDisplayName(context.getString(R.string.add_to_playlist)) .setDisplayName("Add to playlist") .setIconResId(R.drawable.playlist_add) .setSessionCommand(SessionCommand(COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .setExtras(playlistAddExtras) .build(), CommandButton.Builder(CommandButton.ICON_RADIO) .setDisplayName(context.getString(R.string.radio_station)) .setIconResId(R.drawable.radio) .setSessionCommand(SessionCommand(COMMAND_RADIO, Bundle.EMPTY)) .setExtras(radioExtras) .build(), // possibly more here ) // Add all command buttons for media items supported by the session. val session = MediaSession.Builder(context, player) .setCommandButtonsForMediaItems(allCommandButtons) .build()
Java
ImmutableList<CommandButton> allCommandButtons = ImmutableList.of( new CommandButton.Builder(CommandButton.ICON_PLAYLIST_ADD) .setDisplayName("Add to playlist") .setIconUri(Uri.parse("http://www.example.com/icon/playlist_add")) .setSessionCommand(new SessionCommand(COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .setExtras(playlistAddExtras) .build(), new CommandButton.Builder(CommandButton.ICON_RADIO) .setDisplayName("Radio station") .setIconUri(Uri.parse("http://www.example.com/icon/radio")) .setSessionCommand(new SessionCommand(COMMAND_RADIO, Bundle.EMPTY)) .setExtras(radioExtras) .build()); // Add all command buttons for media items supported by the session. MediaSession session = new MediaSession.Builder(context, player) .setCommandButtonsForMediaItems(allCommandButtons) .build();
セッション アプリは、メディア アイテムをビルドするときに、セッションの作成時に設定されたコマンドボタンのセッション コマンドを参照する、サポートされているコマンド ID のセットを追加できます。
Kotlin
val mediaItem = MediaItem.Builder() .setMediaMetadata( MediaMetadata.Builder() .setSupportedCommands(listOf(COMMAND_PLAYLIST_ADD, COMMAND_RADIO)) .build()) .build()
Java
MediaItem mediaItem = new MediaItem.Builder() .setMediaMetadata( new MediaMetadata.Builder() .setSupportedCommands(ImmutableList.of(COMMAND_PLAYLIST_ADD, COMMAND_RADIO)) .build()) .build();
コントローラまたはブラウザがセッション Callback
の別のメソッドに接続または呼び出すと、セッション アプリはコールバックに渡された ControllerInfo
を検査して、コントローラまたはブラウザが表示できるコマンドボタンの最大数を取得できます。コールバック メソッドに渡された ControllerInfo
は、この値に簡単にアクセスできるゲッターを提供します。デフォルトでは値は 0 に設定され、ブラウザまたはコントローラがこの機能をサポートしていないことを示します。
Kotlin
override fun onGetItem( session: MediaLibrarySession, browser: MediaSession.ControllerInfo, mediaId: String, ): ListenableFuture<LibraryResult<MediaItem>> { val settableFuture = SettableFuture.create<LibraryResult<MediaItem>>() val maxCommandsForMediaItems = browser.maxCommandsForMediaItems scope.launch { loadMediaItem(settableFuture, mediaId, maxCommandsForMediaItems) } return settableFuture }
Java
@Override public ListenableFuture<LibraryResult<MediaItem>> onGetItem( MediaLibraryService.MediaLibrarySession session, ControllerInfo browser, String mediaId) { SettableFuture<LibraryResult<MediaItem>> settableFuture = SettableFuture.create(); int maxCommandsForMediaItems = browser.getMaxCommandsForMediaItems(); loadMediaItemAsync(settableFuture, mediaId, maxCommandsForMediaItems); return settableFuture; }
メディア アイテムに対して送信されたカスタム アクションを処理するときに、セッション アプリは onCustomCommand
に渡された引数 Bundle
からメディア アイテム ID を取得できます。
Kotlin
override fun onCustomCommand( session: MediaSession, controller: MediaSession.ControllerInfo, customCommand: SessionCommand, args: Bundle, ): ListenableFuture<SessionResult> { val mediaItemId = args.getString(MediaConstants.EXTRA_KEY_MEDIA_ID) return if (mediaItemId != null) handleCustomCommandForMediaItem(controller, customCommand, mediaItemId, args) else handleCustomCommand(controller, customCommand, args) }
Java
@Override public ListenableFuture<SessionResult> onCustomCommand( MediaSession session, ControllerInfo controller, SessionCommand customCommand, Bundle args) { String mediaItemId = args.getString(MediaConstants.EXTRA_KEY_MEDIA_ID); return mediaItemId != null ? handleCustomCommandForMediaItem(controller, customCommand, mediaItemId, args) : handleCustomCommand(controller, customCommand, args); }
コマンドボタンをブラウザまたはコントローラとして使用する
MediaController
側では、アプリは MediaController
または MediaBrowser
の作成時に、メディア アイテムでサポートするコマンド ボタンの最大数を宣言できます。
Kotlin
val browserFuture = MediaBrowser.Builder(context, sessionToken) .setMaxCommandsForMediaItems(3) .buildAsync()
Java
ListenableFuture<MediaBrowser> browserFuture = new MediaBrowser.Builder(context, sessionToken) .setMaxCommandsForMediaItems(3) .buildAsync();
セッションに接続すると、コントローラ アプリは、メディア アイテムでサポートされているコマンドボタンを受信できます。このコマンドボタンに対して、コントローラがセッション アプリから使用可能なコマンド権限を付与されている必要があります。
Kotlin
val commandButtonsForMediaItem: List<CommandButton> = controller.getCommandButtonsForMediaItem(mediaItem)
Java
ImmutableList<CommandButton> commandButtonsForMediaItem = controller.getCommandButtonsForMediaItem(mediaItem);
便利なように、MediaController
は MediaController.sendCustomCommand(SessionCommand, MediaItem, Bundle)
を使用してメディア アイテム固有のカスタム コマンドを送信できます。
Kotlin
controller.sendCustomCommand(addToPlaylistButton.sessionCommand!!, mediaItem, Bundle.EMPTY)
Java
controller.sendCustomCommand( checkNotNull(addToPlaylistButton.sessionCommand), mediaItem, Bundle.EMPTY);