MediaSession — komponenta frameworku Android pro správu přehrávání multimediálního obsahu a integraci s externími zařízeními. Poskytuje jednotné rozhraní pro interakci s Bluetooth headsety, sluchátky, Android Auto a systémovým mediálním centrem. Podle Android Developers Guide, 2026, MediaSession nahrazuje zastaralý RemoteControlClient a je povinný pro přehrávače synchronizující se se systémem.
Hlavní body
MediaSession — je systémová komponenta Androidu, která umožňuje aplikaci deklarovat svou mediální aktivitu a přijímat řídicí příkazy zvenčí. Když uživatel stiskne tlačítko Play na Bluetooth headsetu, systém předá tuto událost aktivní MediaSession a aplikace reaguje prostřednictvím svého Callbacku.
Před Androidem 5.0 se pro tyto účely používal RemoteControlClient, ale neposkytoval potřebnou flexibilitu a nepodporoval moderní scénáře — Android Auto, chytré hodinky, chytré reproduktory. MediaSession byl zaveden v API 21 a stal se de facto standardem pro všechny aplikace pro Android s přehráváním audia a videa.
Podle Android Developer Documentation (2026) by aplikace měla vytvořit jednu MediaSession pro každý nezávislý zdroj přehrávání. V jednom okamžiku může být pouze jedna aktivní relace — každá nová relace automaticky deaktivuje předchozí.
Kombinace MediaSession s MediaBrowserService poskytuje úplný cyklus správy médií: služba poskytuje strom obsahu (playlisty, katalogy) a relace přijímá příkazy navigace a přehrávání. Toto je architektura doporučená Googlem pro hudební přehrávače, podcasty a audioknihy.
MediaBrowserService běží jako foreground-service s oznámením, což zaručuje fungování aplikace i po ukončení Activity. To je kriticky důležité pro audio přehrávače, které musí pokračovat v přehrávání při minimalizované aplikaci.
Relace podporuje dva typy interakce: přijímá příkazy od MediaController (klientská strana) a vysílá stav prostřednictvím PlaybackState. MediaController může být ve stejném procesu nebo v samostatné aplikaci — systém směruje požadavky přes SessionToken.
Když uživatel zavolá hlasového asistenta Androidu a řekne „Přehrát další skladbu“, systém najde aktivní MediaSession podle propojení s MediaBrowserService a pošle příkaz ACTION_SKIP_TO_NEXT. Callback aplikace obdrží volání onSkipToNext() a aktualizuje PlaybackState.
Aktualizace PlaybackState prostřednictvím setPlaybackState() okamžitě informuje všechny připojené MediaController. Systémové mediální centrum, zařízení Bluetooth a Android Auto obdrží aktualizaci současně — zpoždění za normálních podmínek nepřesahuje 50 ms.
PlaybackState obsahuje klíčové příznaky stavu: isPlaying, pozici, rychlost, dostupné akce (play, pause, seek, stop). Bez správně vyplněného PlaybackState systém neví, jaké příkazy aplikace podporuje, a neposílá odpovídající události.
Metadata (MediaMetadata) doplňují stav informacemi o aktuální skladbě — title, artist, album art URI. Android Auto a nositelná zařízení používají MediaMetadata k zobrazení informací na obrazovce. Podle Google I/O 2024 správné vyplnění MediaMetadata zvyšuje viditelnost aplikace v externích spouštěčích o 40%.
Architektura MediaSession se skládá ze čtyř vzájemně propojených komponent, z nichž každá řeší svůj úkol. Vývojář musí implementovat všechny čtyři pro plnou integraci se systémem.
Relace se vytváří v onCreate služby nebo Activity voláním MediaSessionCompat(context, tag). Po vytvoření je nutné zavolat setFlags(FLAG_HANDLES_MEDIA_BUTTONS | FLAG_HANDLES_TRANSPORT_CONTROLS). V onDestroy se volá release() pro uvolnění systémových prostředků.
Nesprávná správa životního cyklu je jednou z častých chyb. Pokud se nezavolá release(), relace zůstává v systému a následující aplikace může získat falešný stav. Android 13+ zobrazuje varování v Logcat při úniku relace.
Základní integrace začíná vytvořením relace a implementací Callbacku. Doporučuje se používat MediaSessionCompat z knihovny AndroidX media, která poskytuje jednotné API pro všechny verze Androidu — od API 14 do 35.
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()
}
}
V příkladu se vytváří MediaSession s tagem MusicService a příznaky pro zpracování mediálních tlačítek. Callback implementuje onPlay a onPause, aktualizuje PlaybackState. Metoda setActions deklaruje dostupné akce, které systém zobrazuje na uzamčené obrazovce a v mediálním centru.
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)
}
Metadata by se měla aktualizovat při každé změně skladby. Systém používá METADATA_KEY_TITLE a METADATA_KEY_ARTIST k zobrazení informací na Bluetooth displejích automobilů a nositelných zařízeních. Pokud není nastaveno URI obalu, přehrávač zobrazí šedý placeholder.
Bluetooth headsety odesílají příkazy prostřednictvím profilu AVRCP 1.6+. Android přenáší tyto příkazy do intentů ACTION_MEDIA_BUTTON, které jsou zachyceny MediaSession při nastaveném příznaku FLAG_HANDLES_MEDIA_BUTTONS.
Když uživatel stiskne tlačítko Play na Bluetooth sluchátkách, systém vytvoří KeyEvent s kódem KEYCODE_MEDIA_PLAY, který je odeslán do metody onMediaButtonEvent Callbacku. Pokud je v Callbacku implementován onPlay(), systém jej volá přímo. Při jednoduchém stisknutí tlačítka na headsetu se odesílá KEYCODE_MEDIA_PLAY_PAUSE — přehrávač by měl přepnout stav.
Moderní Bluetooth sluchátka mohou mít až 5 tlačítek: hlasitost +/-, play/pause, next, previous. Každé tlačítko generuje vlastní KeyEvent, který musí být správně zpracován Callbackem. Dvojité stisknutí play/pause je obvykle interpretováno jako přeskočení na další skladbu (ACTION_SKIP_TO_NEXT) na mnoha sluchátkách.
Podle Android Compatibility Definition Document (2026) jsou všechny aplikace s multimediálním obsahem povinny správně zpracovávat KEYCODE_MEDIA_PLAY_PAUSE. Ignorování tohoto požadavku vede k automatickému snížení hodnocení aplikace v Google Play pro kategorii Hudba a Audio.
Od Androidu 11 zobrazuje systémové mediální centrum (Media Control Panel) až 5 nedávných MediaSession v panelu oznámení. Uživatel může ovládat přehrávač bez otevření aplikace. Pro správné zobrazení je nutné implementovat MediaBrowserService a správně vyplňovat PlaybackState.
Media Control Panel zobrazuje: název skladby, interpreta, obal (z MediaMetadata), ovládací tlačítka (z povolených akcí PlaybackState). Pokud aplikace neaktualizuje PlaybackState alespoň jednou za 10 sekund během aktivního přehrávání, mediální centrum skryje relaci z panelu.
private fun startForegroundService() {
val notification = NotificationCompat.Builder(this, "media_channel")
.setSmallIcon(R.drawable.ic_play)
.setContentTitle("Právě hraje")
.setContentText(currentTrackTitle)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setStyle(
androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(mediaSession.sessionToken)
)
.build()
startForeground(1001, notification)
}
Oznámení MediaStyle je propojeno s MediaSession prostřednictvím sessionToken a zobrazuje standardní mediální tlačítka. Bez MediaStyle bude oznámení vypadat jako běžné upozornění bez ovládacích tlačítek. Android 13+ vyžaduje explicitní povolení POST_NOTIFICATIONS pro zobrazení.
Často kladené otázky
Technicky ano, ale v daném okamžiku je pouze jedna relace považována za aktivní. Při vytváření nové relace bez volání setActive(true) zůstává předchozí aktivní. Doporučuje se mít jednu relaci na aplikaci nebo na každý nezávislý zdroj zvuku s přepínáním aktivního stavu.
MediaSession nespravuje Audio Focus automaticky — to je samostatný mechanismus. Při příjmu příkazu onPlay vývojář samostatně požaduje AudioFocus přes AudioManager a při ztrátě fokusu pozastaví přehrávání prostřednictvím relace.
Zkontrolujte nastavení příznaků FLAG_HANDLES_MEDIA_BUTTONS a FLAG_HANDLES_TRANSPORT_CONTROLS. Také se ujistěte, že je relace aktivní (setActive(true)). Na Android 12+ fungují mediální tlačítka pouze přes MediaSession — starý registerMediaButtonEventReceiver není podporován.
Pro základní zpracování tlačítek — ne. Ale pro integraci s Android Auto, Wear OS a systémovým mediálním centrem je MediaBrowserService vyžadován. Google doporučuje implementovat MediaBrowserService ve všech aplikacích s dlouhodobým přehráváním audia.
Použijte příkaz adb shell dumpsys media_session pro zobrazení aktivních relací, jejich Callbacků a PlaybackState. Nástroj zobrazí všechny registrované relace s tagem, aktivitou a posledním známým stavem — pohodlný nástroj pro ladění.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také