Ada dua cara untuk terhubung ke aplikasi Media:
MediaControllerMediaBrowser
MediaController
Pengontrol media berinteraksi dengan sesi media untuk membuat kueri dan mengontrol pemutaran aplikasi media. Di Media3, MediaController API mengimplementasikan Player
antarmuka. Contoh aplikasi klien yang menggunakan pengontrol media mencakup:
- Kontrol media sistem Android
- Aplikasi pendamping Android Wear OS
- Android Auto dan Automotive OS
- Asisten suara, seperti Asisten Google
- Aplikasi Pengujian Pengontrol Media
Pengontrol media juga dapat berguna dalam aplikasi media, misalnya jika pemutar dan sesi media berada di Service yang terpisah dari Activity atau Fragment dengan UI.
Membuat MediaController
Untuk membuat MediaController, mulailah dengan membuat SessionToken untuk MediaSession yang sesuai. Metode onStart() dari Activity atau Fragment dapat menjadi tempat yang tepat untuk hal ini.
Kotlin
val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))
Java
SessionToken sessionToken = new SessionToken(context, new ComponentName(context, PlaybackService.class));
Menggunakan SessionToken ini untuk kemudian membuat MediaController akan menghubungkan pengontrol ke sesi yang diberikan. Hal ini terjadi secara asinkron, jadi Anda harus memproses hasilnya dan menggunakannya jika tersedia.
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());
Menggunakan MediaController
MediaController mengimplementasikan antarmuka Player, sehingga Anda dapat menggunakan perintah yang ditentukan dalam antarmuka untuk mengontrol pemutaran MediaSession yang terhubung.
Artinya, memanggil play() di MediaController akan mengirimkan perintah ke MediaSession yang terhubung, yang selanjutnya akan mendelegasikan perintah ke Player yang mendasarinya.
Anda dapat menambahkan Player.Listener ke pengontrol untuk memproses perubahan dalam
Player status. Lihat panduan Peristiwa pemutar untuk mengetahui detail selengkapnya tentang penggunaan
Player.Listener.
Antarmuka MediaController.Listener menentukan callback tambahan untuk peristiwa dan perintah kustom dari MediaSession yang terhubung. Contohnya adalah
onCustomCommand() saat sesi mengirimkan perintah kustom,
onAvailableSessionCommandsChanged() saat sesi mengubah perintah sesi yang tersedia
atau onDisconnected() saat pengontrol terputus
dari sesi.
MediaController.Listener dapat ditetapkan saat membuat pengontrol dengan Builder:
Kotlin
val controllerFuture = MediaController.Builder(context, sessionToken) .setListener( object : MediaController.Listener { override fun onCustomCommand( controller: MediaController, command: SessionCommand, args: Bundle, ): ListenableFuture<SessionResult> { // Handle custom command. return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) } override fun onDisconnected(controller: MediaController) { // Handle disconnection. } } ) .buildAsync()
Java
ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(context, sessionToken) .setListener( new MediaController.Listener() { @Override public ListenableFuture<SessionResult> onCustomCommand( MediaController controller, SessionCommand command, Bundle args) { // Handle custom command. return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS)); } @Override public void onDisconnected(MediaController controller) { // Handle disconnection. } }) .buildAsync();
Seperti komponen lainnya, ingatlah untuk merilis MediaController saat tidak lagi diperlukan, seperti dalam metode onStop() dari Activity atau Fragment.
Kotlin
MediaController.releaseFuture(controllerFuture)
Java
MediaController.releaseFuture(controllerFuture);
Merilis pengontrol akan tetap mengirimkan semua perintah tertunda yang dikirim ke sesi dan hanya melepaskan ikatan dari layanan sesi setelah perintah ini ditangani atau setelah periode waktu tunggu, mana pun yang terjadi lebih dulu.
MediaBrowser
MediaBrowser dibuat berdasarkan kemampuan yang ditawarkan oleh MediaController untuk juga memungkinkan penjelajahan koleksi media yang ditawarkan oleh MediaLibraryService aplikasi media.
Membuat MediaBrowser
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());
Menggunakan MediaBrowser
Untuk mulai menjelajahi koleksi konten aplikasi media, pertama-tama ambil node root dengan 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());
Kemudian, Anda dapat menavigasi koleksi media dengan mengambil turunan MediaItem di koleksi dengan getChildren(). Misalnya, untuk mengambil turunan node root 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());
Menampilkan kontrol pemutaran untuk aplikasi media lain
Saat menampilkan kontrol UI dengan tombol untuk aplikasi media lain, penting untuk mengikuti preferensi tombol media yang dideklarasikan dari aplikasi tersebut.
Untuk mengatasi preferensi aplikasi dengan batasan dan persyaratan UI Anda, gunakan CommandButton.DisplayConstraints. Anda dapat menentukan batas dan
batasan yang dapat dilakukan UI, dan metode resolve() menyediakan daftar tombol yang pasti untuk ditampilkan dengan ikon, posisi, dan
tindakan yang dimaksud. Jika pengguna mengklik salah satu tombol ini, Anda dapat menggunakan CommandButton.executeAction untuk memicu tindakan terkait di aplikasi media.
Kotlin
// Get media button preferences from media app val mediaButtonPreferences = controller.getMediaButtonPreferences() // Declare constraints of UI (example: limit overflow button to one) val displayConstraints = DisplayConstraints.Builder().setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1).build() // Resolve media app preferences with constraints val resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller) // Display buttons in UI for (button in resolvedButtons) { generateUiButton( uiPosition = button.slots[0], icon = getIconRes(button.icon), onClick = { button.executeAction(controller) }, ) }
Java
// Get media button preferences from media app List<CommandButton> mediaButtonPreferences = controller.getMediaButtonPreferences(); // Declare constraints of UI (example: limit overflow button to one) DisplayConstraints displayConstraints = new DisplayConstraints.Builder() .setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1) .build(); // Resolve media app preferences with constraints List<CommandButton> resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller); // Display buttons in UI for (CommandButton button : resolvedButtons) { generateUiButton( /* uiPosition= */ button.slots.get(0), /* icon= */ getIconRes(button.icon), /* onClick= */ () -> button.executeAction(controller)); }