Połącz z aplikacją do multimediów

Kontroler multimediów wchodzi w interakcję z sesją multimediów, aby wysyłać zapytania do aplikacji multimediów i sterować odtwarzaniem. W Media3 interfejs API MediaController implementuje interfejs Player. Przykłady aplikacji klienckich, które korzystają z kontrolera multimediów:

Kontroler multimediów może być też przydatny w aplikacji multimedialnej, na przykład jeśli odtwarzacz i sesja multimediów znajdują się w Service oddzielnie od Activity lub Fragment z interfejsem.

Tworzenie MediaController

Aby utworzyć MediaController, zacznij od utworzenia SessionToken dla odpowiadającego mu MediaSession. Możesz użyć metody onStart() w klasie Activity lub Fragment.

Kotlin

val sessionToken =
  SessionToken(context, ComponentName(context, PlaybackService::class.java))

Java

SessionToken sessionToken =
  new SessionToken(context, new ComponentName(context, PlaybackService.class));

Użycie tego SessionToken do utworzenia MediaController powoduje połączenie kontrolera z daną sesją. Odbywa się to asynchronicznie, więc musisz nasłuchiwać wyniku i używać go, gdy będzie dostępny.

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());

Użyj MediaController

MediaController implementuje interfejs Player, więc możesz używać poleceń zdefiniowanych w interfejsie do sterowania odtwarzaniem połączonego urządzenia MediaSession. Oznacza to, że wywołanie play() na MediaController spowoduje wysłanie polecenia do połączonego MediaSession, który następnie deleguje polecenie do Player.

Aby słuchać zmian stanu Player, możesz dodać do kontrolera Player.Listener. Więcej informacji o używaniu tagu Player.Listener znajdziesz w przewodniku Zdarzenia dotyczące gracza.

Interfejs MediaController.Listener definiuje dodatkowe wywołania zwrotne zdarzeń i komend niestandardowych z połączonego MediaSession. Przykłady: onCustomCommand() gdy sesja wysyła polecenie niestandardowe, onAvailableSessionCommandsChanged() gdy sesja zmienia dostępne polecenia sesji lub onDisconnected() gdy kontroler jest odłączony od sesji.

Podczas kompilowania kontrolera za pomocą Builder można ustawić MediaController.Listener:

Kotlin

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

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();

Podobnie jak w przypadku innych komponentów, pamiętaj, aby zwolnić MediaController, gdy nie jest już potrzebny, np. w metodzie onStop() obiektu Activity lub Fragment.

Kotlin

MediaController.releaseFuture(controllerFuture)

Java

MediaController.releaseFuture(controllerFuture);

Zwolnienie kontrolera spowoduje nadal wysyłanie wszystkich oczekujących poleceń do sesji i odłączenie od usługi sesji dopiero po obsłudze tych poleceń lub po upływie czasu oczekiwania (zależnie od tego, co nastąpi wcześniej).

Tworzenie i używanie MediaBrowser

MediaBrowser rozszerza możliwości oferowane przez MediaController, umożliwiając też przeglądanie biblioteki multimediów oferowanej przez MediaLibraryService w aplikacji do obsługi multimediów.

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());

Aby zacząć przeglądać bibliotekę multimediów aplikacji, najpierw pobierz węzeł główny za pomocą funkcji 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());

Następnie możesz poruszać się po bibliotece multimediów, pobierając elementy podrzędne elementu MediaItem w bibliotece za pomocą elementu getChildren(). Aby na przykład pobrać podelementy węzła głównego 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());

wyświetlać elementy sterujące odtwarzaniem w innej aplikacji multimedialnej.

Podczas wyświetlania elementów sterujących interfejsu z przyciskami innej aplikacji multimedialnej należy przestrzegać zadeklarowanych preferencji dotyczących przycisków multimedialnych tej aplikacji.

Najlepszym sposobem na rozwiązanie konfliktu między preferencjami aplikacji a ograniczeniami i wymaganiami interfejsu jest użycie CommandButton.DisplayConstraints. Możesz określić limity i ograniczenia interfejsu użytkownika, a metoda resolve zawiera listę przycisków do wyświetlenia wraz z ich ikoną, pozycją i zamierzonym działaniem.