MediaSession — conceitos-chave, integração e mecanismo de funcionamento no Android

Autor: IT Sectr Publicado: 2026-05-23 Tempo de leitura: 8 min

MediaSession é um componente do framework Android para gerenciar a reprodução de conteúdo multimídia e integrar-se com dispositivos externos. Ele fornece uma interface unificada para interagir com fones de ouvido Bluetooth, headsets, Android Auto e o centro de mídia do sistema. De acordo com Android Developers Guide, 2026, o MediaSession substitui o obsoleto RemoteControlClient e é obrigatório para players que sincronizam com o sistema.

Principais conclusões

  • MediaSession é o componente central para gerenciar fluxos de mídia no Android, recebendo comandos de fontes externas.
  • Suporta Bluetooth AVRCP, headsets, Android Auto, dispositivos vestíveis e o centro de mídia do Android.
  • A sessão sincroniza o estado do player (play/pause/next/previous) e metadados (título, artista, capa) com o sistema.
  • Requer MediaSessionCompat do AndroidX, fornecendo compatibilidade retroativa até API 14.
  • O sistema de Callback MediaSession.Callback processa comandos recebidos e altera o estado do MediaSession.

O que é MediaSession?

MediaSession é um componente do sistema Android que permite a uma aplicação declarar sua atividade multimídia e receber comandos de controle de fontes externas. Quando o usuário pressiona o botão Play em um headset Bluetooth, o sistema passa este evento para a MediaSession ativa, e a aplicação responde através do seu Callback.

Antes do Android 5.0, o RemoteControlClient era usado para esse fim, mas não fornecia flexibilidade suficiente e não suportava cenários modernos — Android Auto, smartwatches, smart speakers. O MediaSession foi introduzido na API 21 e tornou-se o padrão de facto para todas as aplicações Android com reprodução de áudio e vídeo.

De acordo com a Documentação do Desenvolvedor Android (2026), uma aplicação deve criar uma MediaSession para cada fonte de reprodução independente. Em qualquer momento, apenas uma sessão pode estar ativa — qualquer nova sessão desativa automaticamente a anterior.

MediaSession e MediaBrowserService

A combinação do MediaSession com o MediaBrowserService fornece um ciclo completo de gerenciamento de mídia: o serviço oferece uma árvore de conteúdo (playlists, catálogos) e a sessão aceita comandos de navegação e reprodução. Esta é a arquitetura recomendada pelo Google para players de música, podcasts e audiolivros.

O MediaBrowserService executa como um serviço em primeiro plano com uma notificação, garantindo que a aplicação continue funcionando mesmo quando a Activity é destruída. Isso é crítico para players de áudio que devem continuar tocando quando a aplicação está minimizada.

Como o MediaSession funciona

A sessão suporta dois tipos de interação: recebe comandos do MediaController (o lado cliente) e transmite o estado através do PlaybackState. O MediaController pode estar no mesmo processo ou em uma aplicação separada — o sistema roteia as solicitações através do SessionToken.

Quando o usuário chama o assistente de voz do Android e diz “Toque a próxima faixa”, o sistema encontra a MediaSession ativa através da sua conexão com o MediaBrowserService e envia o comando ACTION_SKIP_TO_NEXT. O Callback da aplicação recebe a chamada onSkipToNext() e atualiza o PlaybackState.

Atualizar o PlaybackState via setPlaybackState() notifica imediatamente todas as instâncias do MediaController conectadas. O centro de mídia do sistema, o dispositivo Bluetooth e o Android Auto recebem a atualização simultaneamente — o atraso não excede 50 ms em condições normais.

PlaybackState e seus metadados

O PlaybackState contém flags de estado chave: isPlaying, posição, velocidade, ações disponíveis (play, pause, seek, stop). Sem um PlaybackState devidamente preenchido, o sistema não sabe quais comandos a aplicação suporta e não envia os eventos correspondentes.

Os metadados (MediaMetadata) complementam o estado com informações sobre a faixa atual — título, artista, URI da capa do álbum. O Android Auto e os smartwatches usam o MediaMetadata para exibir informações na tela. De acordo com o Google I/O 2024, o preenchimento correto do MediaMetadata aumenta a visibilidade da aplicação em launchers de terceiros em 40%.

Componentes-chave do MediaSession

A arquitetura do MediaSession consiste em quatro componentes interconectados, cada um com sua função. O desenvolvedor precisa implementar todos os quatro para uma integração completa com o sistema.

  • MediaSessionCompat — a classe principal da sessão, criada com uma tag de aplicação e aceitando um PendingIntent para botões de mídia.
  • MediaSession.Callback — o manipulador de comandos. Implementa onPlay, onPause, onSkipToNext, onSeekTo e outros métodos.
  • PlaybackStateCompat — o estado atual do player. Contém flags, posição, velocidade e a lista de ações disponíveis.
  • MediaMetadataCompat — metadados da mídia atual: título, artista, álbum, capa, duração.

Ciclo de vida do MediaSession

A sessão é criada no método onCreate de um serviço ou Activity chamando MediaSessionCompat(context, tag). Após a criação, setFlags(FLAG_HANDLES_MEDIA_BUTTONS | FLAG_HANDLES_TRANSPORT_CONTROLS) deve ser chamado. Em onDestroy, release() é chamado para liberar recursos do sistema.

O gerenciamento incorreto do ciclo de vida é um dos erros mais comuns. Se release() não for chamado, a sessão permanece no sistema e a próxima aplicação pode receber um estado obsoleto. O Android 13+ exibe um aviso no Logcat para vazamentos de sessão.

Integrando MediaSession na aplicação

A integração básica começa criando uma sessão e implementando um Callback. Recomenda-se usar MediaSessionCompat da biblioteca AndroidX media, que fornece uma API unificada para todas as versões do Android — da API 14 à 35.

Criação do MediaSession e Callback

kotlin
class MusicService : Service() {

    private lateinit var mediaSession: MediaSessionCompat
    private lateinit var stateBuilder: PlaybackStateCompat.Builder

    override fun onCreate() {
        super.onCreate()

        mediaSession = MediaSessionCompat(this, "MusicService")
        mediaSession.setFlags(
            MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
                or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
        )
        mediaSession.setCallback(MediaSessionCallback())
        updatePlaybackState(false)
    }

    private inner class MediaSessionCallback : MediaSessionCompat.Callback() {
        override fun onPlay() {
            updatePlaybackState(true)
        }

        override fun onPause() {
            updatePlaybackState(false)
        }
    }

    private fun updatePlaybackState(isPlaying: Boolean) {
        stateBuilder = PlaybackStateCompat.Builder()
            .setState(
                if (isPlaying) PlaybackStateCompat.STATE_PLAYING
                else PlaybackStateCompat.STATE_PAUSED,
                AudioTrackCompat.CURRENT_POSITION_NOT_SET,
                1.0f
            )
            .setActions(
                PlaybackStateCompat.ACTION_PLAY
                    or PlaybackStateCompat.ACTION_PAUSE
                    or PlaybackStateCompat.ACTION_SKIP_TO_NEXT
                    or PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
            )
        mediaSession.setPlaybackState(stateBuilder.build())
    }

    override fun onDestroy() {
        mediaSession.release()
        super.onDestroy()
    }
}

Neste exemplo, um MediaSession é criado com a tag MusicService e flags para lidar com botões de mídia. O Callback implementa onPlay e onPause, atualizando o PlaybackState. O método setActions declara as ações disponíveis que o sistema exibe na tela de bloqueio e no centro de mídia.

Definindo MediaMetadata

kotlin
private fun setMetadata(title: String, artist: String) {
    val metadata = MediaMetadataCompat.Builder()
        .putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
        .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
        .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, 300000L)
        .putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, albumArtUrl)
        .build()
    mediaSession.setMetadata(metadata)
}

Os metadados devem ser atualizados a cada mudança de faixa. O sistema usa METADATA_KEY_TITLE e METADATA_KEY_ARTIST para exibir informações em displays Bluetooth de carros e dispositivos vestíveis. Se o URI da capa não for definido, o player mostrará um placeholder cinza.

Lidando com comandos de mídia do Bluetooth e fones de ouvido

Os headsets Bluetooth enviam comandos através do perfil AVRCP 1.6+. O Android transmite esses comandos como intents ACTION_MEDIA_BUTTON, que são interceptados pelo MediaSession quando a flag FLAG_HANDLES_MEDIA_BUTTONS está definida.

Quando o usuário pressiona o botão Play em fones de ouvido Bluetooth, o sistema cria um KeyEvent com o código KEYCODE_MEDIA_PLAY, que é despachado para o método onMediaButtonEvent do Callback. Se onPlay() estiver implementado no Callback, o sistema o chama diretamente. Um único pressionamento do botão do headset envia KEYCODE_MEDIA_PLAY_PAUSE — o player deve alternar o estado.

Lidando com cenários complexos com múltiplos botões

Fones de ouvido Bluetooth modernos podem ter até 5 botões: volume +/-, play/pause, next, previous. Cada botão gera seu próprio KeyEvent, que deve ser tratado corretamente pelo Callback. Um pressionamento duplo de play/pause é tipicamente interpretado como pular para a próxima faixa (ACTION_SKIP_TO_NEXT) em muitos headsets.

De acordo com o Documento de Definição de Compatibilidade do Android (2026), todas as aplicações com conteúdo multimídia devem tratar corretamente o KEYCODE_MEDIA_PLAY_PAUSE. Ignorar este requisito leva a uma diminuição automática da classificação no Google Play para a categoria Música e Áudio.

Sincronizando com o centro de mídia do sistema

A partir do Android 11, o centro de mídia do sistema (Painel de Controle de Mídia) exibe até 5 sessões recentes do MediaSession na gaveta de notificações. O usuário pode controlar o player sem abrir a aplicação. Para exibição correta, é necessário implementar o MediaBrowserService e preencher corretamente o PlaybackState.

O Painel de Controle de Mídia mostra: título da faixa, artista, capa (do MediaMetadata), botões de controle (das ações disponíveis do PlaybackState). Se a aplicação não atualizar o PlaybackState pelo menos uma vez a cada 10 segundos durante a reprodução ativa, o centro de mídia oculta a sessão do painel.

Serviço em primeiro plano com notificação

kotlin
private fun startForegroundService() {
    val notification = NotificationCompat.Builder(this, "media_channel")
        .setSmallIcon(R.drawable.ic_play)
        .setContentTitle("Tocando agora")
        .setContentText(currentTrackTitle)
        .setPriority(NotificationCompat.PRIORITY_LOW)
        .setStyle(
            androidx.media.app.NotificationCompat.MediaStyle()
                .setMediaSession(mediaSession.sessionToken)
        )
        .build()
    startForeground(1001, notification)
}

A notificação MediaStyle se conecta ao MediaSession através do sessionToken e exibe botões de mídia padrão. Sem o MediaStyle, a notificação aparecerá como um alerta comum sem botões de controle. O Android 13+ requer permissão explícita POST_NOTIFICATIONS para exibição.

Perguntas frequentes

Uma aplicação pode ter múltiplas MediaSession ativas simultaneamente?

Tecnicamente sim, mas apenas uma sessão é considerada ativa em qualquer momento. Ao criar uma nova sessão sem chamar setActive(true), a anterior permanece ativa. Recomenda-se ter uma sessão por aplicação ou uma por fonte de áudio independente com alternância de estado ativo.

Como o MediaSession interage com o Audio Focus?

O MediaSession não gerencia o Audio Focus automaticamente — este é um mecanismo separado. Ao receber um comando onPlay, o desenvolvedor deve solicitar o AudioFocus através do AudioManager de forma independente e, ao perder o foco, pausar a reprodução através da sessão.

Por que os botões de mídia nos fones de ouvido não funcionam com minha aplicação?

Verifique se as flags FLAG_HANDLES_MEDIA_BUTTONS e FLAG_HANDLES_TRANSPORT_CONTROLS estão definidas. Certifique-se também de que a sessão está ativa (setActive(true)). No Android 12+, os botões de mídia funcionam apenas através do MediaSession — o antigo registerMediaButtonEventReceiver não é suportado.

O MediaBrowserService é necessário para o MediaSession funcionar?

Para manipulação básica de botões — não. Mas para integração com Android Auto, Wear OS e o centro de mídia do sistema, o MediaBrowserService é necessário. O Google recomenda implementar o MediaBrowserService em todas as aplicações com reprodução de áudio prolongada.

Como verificar se o MediaSession está configurado corretamente?

Use o comando adb shell dumpsys media_session para visualizar as sessões ativas, seus Callbacks e PlaybackState. Esta utilidade mostra todas as sessões registradas com suas tags, status de atividade e último estado conhecido — uma ferramenta conveniente para depuração.

Resumo

  • MediaSession é a forma padrão de gerenciar reprodução no Android, substituindo o RemoteControlClient a partir da API 21.
  • A sessão recebe comandos do Bluetooth, fones de ouvido, Android Auto e do centro de mídia do sistema através do sistema de Callback.
  • PlaybackState e MediaMetadata são dois componentes obrigatórios para a sincronização correta com a interface do sistema.
  • A integração é feita através do MediaSessionCompat do AndroidX media, fornecendo compatibilidade com API 14+.
  • Para exibição no centro de mídia do sistema, são necessários MediaBrowserService e um serviço em primeiro plano com notificação MediaStyle.
  • O gerenciamento do Audio Focus é uma tarefa separada não automatizada pelo MediaSession. O desenvolvedor gerencia o foco independentemente.
  • Para depuração, use adb shell dumpsys media_session para visualizar as sessões ativas e seu estado.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também