As sessões de mídia oferecem uma maneira universal de interagir com um áudio ou vídeo de futebol. Ao informar ao Android que a mídia está em reprodução em um app, a reprodução podem ser delegados ao app. A integração com a sessão de mídia permite um app para anunciar a reprodução de mídia externamente e receber comandos de reprodução de fontes externas. Essas fontes podem ser botões físicos (como o botão em um fone de ouvido ou controle remoto da TV) ou comandos indiretos (como com a instrução "pausar" ao Google Assistente). A sessão de mídia delega essas ao aplicativo que os aplica ao player de mídia para o qual transparente onde os comandos foram originados.
Uma sessão de mídia convive com o player que a gerencia. Você deve criar
e inicializar uma sessão de mídia no método onCreate()
da atividade ou
que é proprietário da sessão de mídia e do player associado a ele.
Inicializar a sessão de mídia
Uma sessão de mídia recém-criada não tem recursos. Inicialize a sessão executando estas etapas:
- Defina sinalizações para que a sessão de mídia receba callbacks de controladores de mídia e botões de mídia.
- Crie e inicialize uma instância de
PlaybackStateCompat
e a atribua à sessão. O estado de reprodução muda durante a sessão, por isso recomendamos o cache dePlaybackStateCompat.Builder
para reutilização. - Crie uma instância de
MediaSessionCompat.Callback
e a atribua à sessão. Veja abaixo mais informações sobre callbacks.
Crie e inicialize uma sessão de mídia no método onCreate()
da
atividade
ou serviço proprietário da sessão.
Para que os botões de mídia funcionem,
quando o app é recém-inicializado (ou interrompido), o PlaybackState
precisa
conter uma ação de reprodução correspondente à intent que o botão de mídia envia. Isso é
por que ACTION_PLAY
é atribuído ao estado da sessão durante
inicialização do sistema. Para mais informações, consulte Como responder a mídias
Botões.
Manter o estado de reprodução e os metadados
Há duas classes que representam o estado de uma sessão de mídia.
A
PlaybackStateCompat
descreve o estado operacional atual do player. Isso inclui:
- O estado de transporte, isto é, se o player está em reprodução/pausado/em buffer etc. Veja
getState()
. - Um código de erro e uma mensagem de erro opcional, quando aplicável. Veja
getErrorCode()
e leia Estados e erros, abaixo. - A posição do player
- As ações válidas do controlador que podem ser processadas no estado atual
O MediaMetadataCompat
descreve o material que está sendo reproduzido:
- O nome do artista, álbum e faixa
- A duração da faixa
- Arte do álbum para exibição na tela de bloqueio. A imagem é um bitmap com tamanho máximo de 320 x 320 dp. Se for maior, ela será reduzida.
- Uma instância de
ContentUris
que aponta para uma versão maior da obra de arte
O estado do player e os metadados podem mudar durante a vida útil de uma sessão de mídia. Sempre que o estado ou os metadados mudarem, você precisará usar o builder correspondente para cada classe, PlaybackStateCompat.Builder()
ou MediaMetadataCompat.Builder()
e, em seguida, transmitir a nova instância para a sessão de mídia chamando
setPlaybackState()
ou
setMetaData()
.
Para reduzir o consumo geral de memória em função dessas operações frequentes, uma boa sugestão é criar os builders uma vez e reutilizá-los ao longo da vida da sessão.
Estados e erros
Observe que PlaybackState
é um objeto que contém valores separados para o
estado de reprodução da sessão (getState()
)
e, quando necessário, um código de erro (getErrorCode()
) associado.
Os erros podem ser fatais ou não fatais:
Sempre que a reprodução for interrompida, você deverá gerar um erro fatal: defina o
o estado de transporte para STATE_ERROR
e especificar um erro associado a setErrorMessage(int, CharSequence)
.
Enquanto a reprodução estiver bloqueada pelo erro, a PlaybackState
vai continuar
para informar STATE_ERROR
e o erro.
Um erro não fatal ocorre quando o app não consegue processar uma solicitação, mas pode continuar a jogar:
O transporte permanece em um estado "normal" estado (como STATE_PLAYING
), mas o PlaybackState
contém um código de erro.
Por exemplo, se a última música estiver tocando e o usuário pedir para pular para a próxima,
a reprodução pode continuar, mas é necessário criar uma nova PlaybackState
com o código de erro ERROR_CODE_END_OF_QUEUE
e
depois, chame setPlaybackState()
. Os controladores de mídia anexados à sessão vão receber o callback
onPlaybackStateChanged()
e explique ao usuário o que aconteceu. Um erro não fatal precisar ser informado apenas uma vez, no momento em que ocorre. Na próxima vez que a sessão atualizar o PlaybackState
, não defina o mesmo erro não fatal novamente, a menos que ele tenha ocorrido em resposta a uma nova solicitação.
Telas de bloqueio de sessão de mídia
A partir do Android 4.0 (API de nível 14), o sistema pode acessar o sistema estado de reprodução e metadados. É assim que a tela de bloqueio exibe os controles de mídia e arte. O comportamento varia de acordo com o Versão do Android.
Arte do álbum
Do Android 4.0 (nível 14 da API) ao Android 10 (nível 29 da API), o plano de fundo da tela de bloqueio exibe a capa do álbum, mas somente se a sessão de mídia incluem um bitmap de plano de fundo.
Controles de transporte
Do Android 4.0 (API de nível 14) até o Android 4.4 (API de nível 19), quando uma sessão de mídia está ativa e os metadados da sessão incluem um bitmap em segundo plano, a tela de bloqueio exibe automaticamente os controles de transporte.
No Android 5.0 (API de nível 21) ou versões mais recentes, o sistema não oferece controles na tela de bloqueio. Em vez disso, você deve usar um MediaStyle notificação para exibir controles de transporte.
Adicionar ações personalizadas
Aplicativos de mídia podem definir ações personalizadas; por exemplo: gostei, gostei ou voltar 30 segundos. Uma ação personalizada precisa implementar um comportamento completamente novo. O que fazer não usar uma ação personalizada para substituir uma das ações padrão de controle de transporte; definido em PlaybackStateCompat.
Adicione ações personalizadas com addCustomAction()
. O exemplo a seguir mostra como adicionar um controle para uma ação "Gostei":
Kotlin
stateBuilder.addCustomAction( PlaybackStateCompat.CustomAction.Builder( CUSTOM_ACTION_THUMBS_UP, resources.getString(R.string.thumbs_up), thumbsUpIcon ).run { setExtras(customActionExtras) build() } )
Java
stateBuilder.addCustomAction(new PlaybackStateCompat.CustomAction.Builder( CUSTOM_ACTION_THUMBS_UP, resources.getString(R.string.thumbs_up), thumbsUpIcon) .setExtras(customActionExtras) .build());
Consulte Universal Music Player para ver um exemplo completo.
Você responde à ação com onCustomAction()
.
Kotlin
override fun onCustomAction(action: String, extras: Bundle?) { when(action) { CUSTOM_ACTION_THUMBS_UP -> { ... } } }
Java
@Override public void onCustomAction(@NonNull String action, Bundle extras) { if (CUSTOM_ACTION_THUMBS_UP.equals(action)) { ... } }
Consulte também Universal Music Player (link em inglês).
Callbacks de sessão de mídia
Os principais métodos de callback de sessão de mídia são onPlay()
, onPause()
e onStop()
.
É aqui que você adiciona o código que controla o player.
Como você instancia e define o callback da sessão no tempo de execução (em onCreate()
), o app pode definir callbacks alternativos que usam players diferentes e escolher a combinação apropriada de callback/player de acordo com o dispositivo e/ou nível do sistema. Você pode mudar o player sem mudar o restante do app. Por exemplo, você pode usar ExoPlayer ao executar no Android 4.1 (API de nível 16) ou versões posteriores e usar MediaPlayer
em sistemas anteriores.
Além de controlar o player e gerenciar as transições de estado da sessão de mídia, os callbacks também ativam e desativam recursos do app e controlam a interação com outros apps e o hardware do dispositivo. Consulte Como controlar a saída de áudio.
A implementação dos métodos de callback da sessão de mídia depende da estrutura do app. Consulte as páginas separadas que descrevem como usar callbacks no apps de áudio e apps de vídeo, descrever como implementar callbacks para cada tipo de app.