Bir medya uygulamasına bağlanmanın iki yolu vardır:
MediaControllerMediaBrowser
MediaController
Medya kumandası, bir medya uygulamasının oynatılmasını sorgulamak ve kontrol etmek için medya oturumuyla etkileşim kurar. Media3'te MediaController API'si, Player arayüzünü uygular. Medya kumandası kullanan istemci uygulamalarına örnek olarak şunlar verilebilir:
- Android sistem medya kontrolleri
- Android Wear OS tamamlayıcı uygulaması
- Android Auto ve Automotive OS
- Google Asistan gibi sesli asistanlar
- Medya Kumandası Test uygulaması
Medya kumandası, medya uygulamalarında da faydalı olabilir. Örneğin, oynatıcı ve medya oturumu, kullanıcı arayüzüne sahip Activity veya Fragment öğesinden ayrı bir Service içinde bulunuyorsa medya kumandası kullanılabilir.
MediaController oluşturun
MediaController oluşturmak için ilgili MediaSession için bir SessionToken oluşturarak başlayın. Activity veya Fragment sınıfınızın onStart() yöntemi, bu işlem için uygun bir yer olabilir.
Kotlin
val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))
Java
SessionToken sessionToken = new SessionToken(context, new ComponentName(context, PlaybackService.class));
Bu SessionToken kullanılarak bir MediaController oluşturulduğunda denetleyici, belirtilen oturuma bağlanır. Bu işlem eşzamansız olarak gerçekleşir. Bu nedenle, sonucu dinlemeniz ve kullanılabilir olduğunda kullanmanız gerekir.
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 kullanın
MediaController, Player arayüzünü uygular. Bu sayede, bağlı MediaSession cihazın oynatımını kontrol etmek için arayüzde tanımlanan komutları kullanabilirsiniz.
Yani MediaController üzerinde play() çağrıldığında komut, bağlı MediaSession cihazına gönderilir ve bu cihaz da komutu temelindeki Player cihazına iletir.
Player durumundaki değişiklikleri dinlemek için denetleyiciye bir Player.Listener ekleyebilirsiniz. Player.Listener kullanımı hakkında daha fazla bilgi için Oyuncu etkinlikleri kılavuzuna bakın.
MediaController.Listener arayüzü, bağlı MediaSession cihazdan gelen etkinlikler ve özel komutlar için ek geri çağırmalar tanımlar. Örnekler arasında, oturumun özel bir komut gönderdiği onCustomCommand(), oturumun kullanılabilir oturum komutlarını değiştirdiği onAvailableSessionCommandsChanged() veya denetleyicinin oturumla bağlantısının kesildiği onDisconnected() durumlar yer alır.
Denetleyiciyi Builder ile oluştururken MediaController.Listener ayarlanabilir:
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();
Diğer bileşenlerde olduğu gibi, artık ihtiyaç duyulmadığında (ör. bir Activity veya Fragment öğesinin onStop() yönteminde) MediaController öğesini serbest bırakmayı unutmayın.
Kotlin
MediaController.releaseFuture(controllerFuture)
Java
MediaController.releaseFuture(controllerFuture);
Denetleyiciyi serbest bıraktığınızda, oturuma gönderilen tüm bekleyen komutlar yine de iletilir ve yalnızca bu komutlar işlendikten veya bir zaman aşımı süresinden sonra (hangisi önce gerçekleşirse) oturum hizmetiyle bağlantı kesilir.
MediaBrowser
MediaBrowser, MediaController tarafından sunulan özelliklerin üzerine inşa edilerek medya uygulamasının MediaLibraryService tarafından sunulan medya kitaplığına göz atmayı da sağlar.
MediaBrowser oluşturun
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());
MediaBrowser kullanın
Medya uygulamasının içerik kitaplığına göz atmaya başlamak için önce getLibraryRoot() ile kök düğümü alın:
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());
Ardından, getChildren() ile kitaplıktaki bir MediaItem öğesinin alt öğelerini alarak medya kitaplığında gezinebilirsiniz. Örneğin, kök düğümün (MediaItem) alt öğelerini almak için:
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());
Başka bir medya uygulaması için oynatma kontrollerini gösterme
Başka bir medya uygulaması için düğmeler içeren kullanıcı arayüzü kontrolleri gösterirken, o uygulamanın beyan edilen medya düğmesi tercihlerine uymak önemlidir.
Uygulamanın tercihlerini kullanıcı arayüzünüzün kısıtlamaları ve gereksinimleriyle çözmek için CommandButton.DisplayConstraints kullanın. Kullanıcı arayüzünüzün sınırlarını ve kısıtlamalarını tanımlayabilirsiniz. resolve() yöntemi, simgeleri, konumları ve amaçlanan işlemleriyle birlikte gösterilecek düğmelerin kesin bir listesini sağlar. Kullanıcı bu düğmelerden birini tıklarsa medya uygulamasında ilişkili işlemi tetiklemek için CommandButton.executeAction kullanabilirsiniz.
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)); }