Mit einer Medien-App verbinden

Ein Media Controller interagiert mit einer Mediensitzung, um die Wiedergabe einer Media-App abzufragen und zu steuern. In Media3 implementiert die MediaController API die Player-Schnittstelle. Beispiele für Client-Apps, die einen Media-Controller verwenden:

Ein Media-Controller kann auch in einer Media-App nützlich sein, z. B. wenn sich der Player und die Media-Sitzung in einem Service befinden, das sich vom Activity oder Fragment mit der Benutzeroberfläche unterscheidet.

MediaController erstellen

Wenn Sie ein MediaController erstellen möchten, müssen Sie zuerst ein SessionToken für das entsprechende MediaSession erstellen. Die onStart()-Methode Ihres Activity oder Fragment ist dafür gut geeignet.

Kotlin

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

Java

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

Wenn Sie mit diesem SessionToken einen MediaController erstellen, wird der Controller mit der angegebenen Sitzung verbunden. Dies erfolgt asynchron. Sie sollten also auf das Ergebnis warten und es verwenden, sobald es verfügbar ist.

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 verwenden

MediaController implementiert die Player-Schnittstelle. Daher können Sie die in der Schnittstelle definierten Befehle verwenden, um die Wiedergabe des verbundenen MediaSession zu steuern. Wenn Sie play() für ein MediaController aufrufen, wird der Befehl an das verbundene MediaSession gesendet, das den Befehl dann an das zugrunde liegende Player delegiert.

Sie können dem Controller einen Player.Listener hinzufügen, um auf Änderungen des Player-Status zu reagieren. Weitere Informationen zur Verwendung eines Player.Listener finden Sie im Leitfaden zu Player-Ereignissen.

Die MediaController.Listener-Schnittstelle definiert zusätzliche Callbacks für Ereignisse und benutzerdefinierte Befehle von der verbundenen MediaSession. Beispiele sind onCustomCommand(), wenn in der Sitzung ein benutzerdefinierter Befehl gesendet wird, onAvailableSessionCommandsChanged(), wenn in der Sitzung die verfügbaren Sitzungsbefehle geändert werden, oder onDisconnected(), wenn die Verbindung des Controllers zur Sitzung getrennt wird.

Eine MediaController.Listener kann beim Erstellen des Controllers mit einem Builder festgelegt werden:

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

Wie bei anderen Komponenten sollten Sie die MediaController freigeben, wenn sie nicht mehr benötigt wird, z. B. in der Methode onStop() eines Activity oder Fragment.

Kotlin

MediaController.releaseFuture(controllerFuture)

Java

MediaController.releaseFuture(controllerFuture);

Wenn Sie die Controller-Verbindung trennen, werden alle ausstehenden Befehle, die an die Sitzung gesendet wurden, weiterhin ausgeführt. Die Verbindung zum Sitzungsdienst wird erst getrennt, wenn diese Befehle verarbeitet wurden oder nach einem Zeitüberschreitungszeitraum – je nachdem, was zuerst eintritt.

MediaBrowser erstellen und verwenden

Eine MediaBrowser baut auf den Funktionen einer MediaController auf und ermöglicht auch das Durchsuchen der Mediathek, die von der MediaLibraryService einer Media-App bereitgestellt wird.

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

Wenn Sie die Inhaltsbibliothek der Media-App durchsuchen möchten, rufen Sie zuerst den Stammknoten mit getLibraryRoot() ab:

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

Anschließend können Sie durch die Mediathek navigieren, indem Sie die untergeordneten Elemente eines MediaItem in der Mediathek mit getChildren() abrufen. So rufen Sie beispielsweise die untergeordneten Elemente des Stammknotens MediaItem ab:

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

Wiedergabesteuerung für eine andere Media-App anzeigen

Wenn Sie UI-Steuerelemente mit Schaltflächen für eine andere Media-App anzeigen, müssen Sie die deklarierten Einstellungen für Medientasten dieser App berücksichtigen.

Die beste Möglichkeit, die Einstellungen der App und die Einschränkungen und Anforderungen Ihrer Benutzeroberfläche zu berücksichtigen, ist die Verwendung von CommandButton.DisplayConstraints. Sie können die Grenzen und Einschränkungen Ihrer Benutzeroberfläche festlegen. Die Methode resolve bietet eine genaue Liste der Schaltflächen, die mit ihrem Symbol, ihrer Position und der beabsichtigten Aktion angezeigt werden sollen.