Существует два способа подключения к медиаприложению:
-
MediaController -
MediaBrowser
MediaController
Контроллер мультимедиа взаимодействует с медиасессией для запроса и управления воспроизведением медиаприложения. В Media3 API MediaController реализует интерфейс Player . Примеры клиентских приложений, использующих контроллер мультимедиа, включают:
- Управление воспроизведением в системе Android
- Приложение-компаньон для Android Wear OS
- Android Auto и автомобильная ОС
- Голосовые помощники, такие как Google Assistant
- Приложение для тестирования медиаконтроллера
Контроллер мультимедиа также может быть полезен в рамках медиаприложения, например, если плеер и медиасессия находятся в отдельном Service , отличном от Activity или Fragment с пользовательским интерфейсом.
Создайте MediaController
Для создания MediaController начните с создания SessionToken для соответствующей MediaSession . Для этого хорошо подойдет метод onStart() вашей Activity или Fragment .
Котлин
val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))
Java
SessionToken sessionToken = new SessionToken(context, new ComponentName(context, PlaybackService.class));
Использование этого SessionToken для создания MediaController подключает контроллер к заданной сессии. Это происходит асинхронно, поэтому вам следует отслеживать результат и использовать его, когда он станет доступен.
Котлин
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
MediaController реализует интерфейс Player , поэтому вы можете использовать команды, определенные в этом интерфейсе, для управления воспроизведением подключенной MediaSession . Это означает, что вызов play() на MediaController отправит команду подключенной MediaSession , которая впоследствии передаст команду своему базовому объекту Player .
Вы можете добавить Player.Listener в контроллер, чтобы отслеживать изменения состояния Player . Более подробную информацию об использовании Player.Listener см. в руководстве по событиям игрока .
Интерфейс MediaController.Listener определяет дополнительные функции обратного вызова для событий и пользовательских команд от подключенной сессии MediaSession . Примерами являются onCustomCommand() , когда сессия отправляет пользовательскую команду, onAvailableSessionCommandsChanged() , когда сессия изменяет доступные команды сессии, или onDisconnected() когда контроллер отключается от сессии.
Объект MediaController.Listener можно установить при создании контроллера с помощью Builder :
Котлин
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();
Как и в случае с другими компонентами, не забывайте освобождать MediaController , когда он больше не нужен, например, в методе onStop() Activity или Fragment .
Котлин
MediaController.releaseFuture(controllerFuture)
Java
MediaController.releaseFuture(controllerFuture);
При освобождении контроллера все ожидающие команды, отправленные в сессию, будут доставлены, и он отсоединится от службы сессии только после обработки этих команд или по истечении периода ожидания, в зависимости от того, что произойдет раньше.
MediaBrowser
Компонент MediaBrowser расширяет возможности MediaController и позволяет также просматривать медиатеку, предоставляемую MediaLibraryService медиаприложения.
Создать MediaBrowser
Котлин
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
Чтобы начать просмотр библиотеки контента медиаприложения, сначала получите корневой узел с помощью getLibraryRoot() :
Котлин
// 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());
Затем вы можете перемещаться по медиатеке, получая дочерние элементы элемента MediaItem в библиотеке с помощью getChildren() . Например, чтобы получить дочерние элементы корневого узла MediaItem :
Котлин
// 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());
Отображение элементов управления воспроизведением для другого медиаприложения
При отображении элементов управления пользовательского интерфейса в виде кнопок для другого медиаприложения важно соблюдать заданные в этом приложении параметры кнопок мультимедиа .
Чтобы согласовать настройки приложения с ограничениями и требованиями вашего пользовательского интерфейса, используйте CommandButton.DisplayConstraints . Вы можете определить ограничения и возможности вашего пользовательского интерфейса, а метод resolve предоставляет определенный список кнопок для отображения с их значком, положением и предполагаемым действием. Если пользователь нажимает одну из этих кнопок, вы можете использовать CommandButton.executeAction для запуска соответствующего действия в медиаприложении.
Котлин
// 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)); }