メディアアプリには、階層構造で整理されたメディア アイテムのコレクションが含まれていることがよくあります。 たとえば、アルバム内の曲やプレイリスト内のテレビ番組などです。このメディア アイテムの階層は、メディア ライブラリと呼ばれます。
MediaLibraryService は、メディア ライブラリの提供とアクセスを行うための標準化された API を提供します。たとえば、メディアアプリに
Android Autoのサポートを追加する場合に便利です。Android Auto は、
メディア ライブラリ用の独自の安全運転 UI を提供します。
MediaLibraryService をビルドする
MediaLibraryService の実装は MediaSessionService の実装と似ていますが、onGetSession() メソッドでは MediaSession ではなく MediaLibrarySession を返す必要があります。
Kotlin
class PlaybackService : MediaLibraryService() { private var mediaLibrarySession: MediaLibrarySession? = null private val callback: MediaLibrarySession.Callback = object : MediaLibrarySession.Callback { /* ... */ } override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaLibrarySession? { // 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 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.MediaLibraryService"/>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
サービスは、プラットフォームと Media3 サービス インターフェースの両方として登録することをおすすめします。
プラットフォーム メディア セッション API を使用するクライアントとの互換性を確保するため、
<action android:name="android.media.browse.MediaBrowserService"/>をintent-filter要素に含めることをおすすめします。Media3 は、このサービス インターフェースとの下位互換性を自動的に提供します。将来に備えた設定として、Media3 を使用するアプリが Media3 API を使用してサービスと通信できるようにするには、 プラットフォーム オプションとともに
<action android:name="androidx.media3.session.MediaLibraryService"/>を 指定する必要があります。
これにより、アプリは PackageManager を介してサービスを検索し、これらのインターフェースのいずれかを介して MediaBrowser に接続できます。
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)) .setSessionCommand(SessionCommand(COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .setExtras(playlistAddExtras) .build(), CommandButton.Builder(CommandButton.ICON_RADIO) .setDisplayName(context.getString(R.string.radio_station)) .setSessionCommand(SessionCommand(COMMAND_RADIO, Bundle.EMPTY)) .setExtras(radioExtras) .build(), ) // 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(context.getString(R.string.add_to_playlist)) .setSessionCommand(new SessionCommand(COMMAND_PLAYLIST_ADD, Bundle.EMPTY)) .setExtras(playlistAddExtras) .build(), new CommandButton.Builder(CommandButton.ICON_RADIO) .setDisplayName(context.getString(R.string.radio_station)) .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 loadMediaItemAsync(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 = controller.getCommandButtonsForMediaItem(mediaItem)
Java
ImmutableList<CommandButton> commandButtonsForMediaItem = controller.getCommandButtonsForMediaItem(mediaItem);
Kotlin
val future = controller.sendCustomCommand( requireNotNull(addToPlaylistButton.sessionCommand), mediaItem, Bundle.EMPTY, )
Java
ListenableFuture<SessionResult> future = controller.sendCustomCommand( checkNotNull(addToPlaylistButton.sessionCommand), mediaItem, Bundle.EMPTY);