Подключиться к приложению Media можно двумя способами:
-  
MediaController -  
MediaBrowser 
 MediaController
 Медиа-контроллер взаимодействует с медиа-сессией, запрашивая и управляя воспроизведением медиа-приложения. В Media3 API MediaController реализует интерфейс Player . Примеры клиентских приложений, использующих медиа-контроллер:
- Элементы управления мультимедиа системы Android
 - Приложение-компаньон для ОС Android Wear
 - Android Auto и автомобильная ОС
 - Голосовые помощники, такие как Google Assistant
 - Тестовое приложение Media Controller
 
 Медиа-контроллер также может быть полезен в медиа-приложении, например, если проигрыватель и медиа-сеанс находятся в Service отдельной от Activity или Fragment с пользовательским интерфейсом.
 Создать MediaController
 Чтобы создать MediaController , начните с создания SessionToken для соответствующего MediaSession . Метод onStart() вашей Activity или Fragment может быть хорошим местом для этого. 
Котлин
val sessionToken =
  SessionToken(context, ComponentName(context, PlaybackService::class.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())
Ява
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 : 
Котлин
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()
Ява
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)
Ява
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())
Ява
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())
Ява
// 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())
Ява
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 предоставляет определённый список кнопок для отображения с их значками, положением и предполагаемым действием.