Um controlador de mídia interage com uma sessão de mídia para consultar e controlar a reprodução de um app de mídia. Na Media3, a API MediaController
implementa a interface Player
. Exemplos de apps cliente que usam um controlador de mídia:
- Controles de mídia do sistema Android
- App complementar do Android Wear OS
- Android Auto e Automotive OS
- Assistentes de voz, como o Google Assistente
- O app de teste Media Controller
Um controlador de mídia também pode ser útil em um app de mídia, por exemplo, se o player e a sessão de mídia estiverem em um Service
separado do Activity
ou Fragment
com a interface.
Criar um MediaController
.
Para criar uma MediaController
, comece criando uma SessionToken
para o
MediaSession
correspondente. O método onStart()
da sua Activity
ou
Fragment
pode ser um bom lugar para isso.
Kotlin
val sessionToken =
SessionToken(context, ComponentName(context, PlaybackService::class.java))
Java
SessionToken sessionToken =
new SessionToken(context, new ComponentName(context, PlaybackService.class));
Usar esse SessionToken
para criar um MediaController
conecta o
controlador à sessão especificada. Isso acontece de forma assíncrona, então você precisa
aguardar o resultado e usá-lo quando estiver disponível.
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());
Usar um MediaController
O MediaController
implementa a interface Player
. Assim, é possível usar os comandos
definidos na interface para controlar a reprodução do MediaSession
conectado.
Isso significa que chamar play()
em um MediaController
vai enviar o
comando para o MediaSession
conectado, que vai delegar o
comando ao Player
subjacente.
É possível adicionar um Player.Listener
ao controlador para detectar mudanças no estado
Player
. Consulte o guia Eventos do player para mais detalhes sobre como usar um
Player.Listener
.
A interface MediaController.Listener
define callbacks adicionais para eventos e comandos personalizados do MediaSession
conectado. Por exemplo, onCustomCommand()
quando a sessão envia um comando personalizado, onAvailableSessionCommandsChanged()
quando a sessão muda os comandos disponíveis ou onDisconnected()
quando o controlador é desconectado da sessão.
Uma MediaController.Listener
pode ser definida ao criar o controlador com um
Builder
:
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();
Assim como em outros componentes, libere o MediaController
quando ele não for mais necessário, como no método onStop()
de um Activity
ou Fragment
.
Kotlin
MediaController.releaseFuture(controllerFuture)
Java
MediaController.releaseFuture(controllerFuture);
Liberar o controlador ainda vai entregar todos os comandos pendentes enviados à sessão e só vai desvincular do serviço de sessão depois que esses comandos forem processados ou após um período de tempo limite, o que ocorrer primeiro.
Criar e usar um MediaBrowser
Um MediaBrowser
se baseia nos recursos oferecidos por um
MediaController
para também permitir a navegação na biblioteca de mídia oferecida por um
MediaLibraryService
de app de mídia.
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());
Para começar a navegar pela biblioteca de conteúdo do app de mídia, primeiro recupere o nó raiz
com 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());
Em seguida, navegue pela biblioteca de mídia recuperando os filhos de um
MediaItem
na biblioteca com getChildren()
. Por exemplo, para recuperar os
filhos do nó raiz 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());
Mostrar controles de mídia para outro app de mídia
Ao mostrar controles de interface com botões para outro app de mídia, é importante seguir as preferências de botões de mídia declaradas desse app.
A melhor maneira de resolver as preferências do app e as restrições e
requisitos da sua interface é usar CommandButton.DisplayConstraints
. Você pode
definir limites e restrições do que a interface pode fazer, e o
método resolve
fornece uma lista definida de botões para
mostrar com ícone, posição e ação pretendida.