MediaSession — komponent frameworka Android do zarządzania odtwarzaniem treści multimedialnych i integracji z urządzeniami zewnętrznymi. Zapewnia jednolity interfejs interakcji z zestawami słuchawkowymi Bluetooth, słuchawkami, Android Auto i systemowym centrum multimedialnym. Według Android Developers Guide, 2026, MediaSession zastępuje przestarzały RemoteControlClient i jest obowiązkowy dla odtwarzaczy synchronizujących się z systemem.
Najważniejsze
MediaSession — to systemowy komponent Androida, który pozwala aplikacji zgłosić swoją aktywność multimedialną i przyjmować polecenia sterujące z zewnątrz. Gdy użytkownik naciska przycisk Play na zestawie słuchawkowym Bluetooth, system przekazuje to zdarzenie do aktywnej MediaSession, a aplikacja reaguje poprzez swój Callback.
Przed Androidem 5.0 do tych celów używano RemoteControlClient, ale nie zapewniał on odpowiedniej elastyczności i nie obsługiwał nowoczesnych scenariuszy — Android Auto, zegarków noszonych, inteligentnych głośników. MediaSession został wprowadzony w API 21 i stał się standardem de facto dla wszystkich aplikacji Android z odtwarzaniem audio i wideo.
Według Android Developer Documentation (2026), aplikacja powinna utworzyć jedną MediaSession dla każdego niezależnego źródła odtwarzania. Przy czym w danym momencie może być tylko jedna aktywna sesja — każda nowa sesja automatycznie dezaktywuje poprzednią.
Połączenie MediaSession z MediaBrowserService zapewnia pełny cykl zarządzania mediami: serwis udostępnia drzewo treści (playlisty, katalogi), a sesja przyjmuje polecenia nawigacji i odtwarzania. Jest to architektura zalecana przez Google dla odtwarzaczy muzycznych, podcastów i audiobooków.
MediaBrowserService uruchamia się jako foreground-service z powiadomieniem, co gwarantuje działanie aplikacji nawet po zabiciu Activity. Jest to krytycznie ważne dla odtwarzaczy audio, które muszą kontynuować odtwarzanie przy zminimalizowanej aplikacji.
Sesja obsługuje dwa typy interakcji: przyjmuje polecenia od MediaController (strona kliencka) i transmituje stan poprzez PlaybackState. MediaController może znajdować się w tym samym procesie lub w oddzielnej aplikacji — system kieruje żądania poprzez SessionToken.
Gdy użytkownik wywołuje asystenta głosowego Androida i mówi „Włącz następny utwór”, system znajduje aktywną MediaSession po powiązaniu z MediaBrowserService i wysyła polecenie ACTION_SKIP_TO_NEXT. Callback aplikacji otrzymuje wywołanie onSkipToNext() i aktualizuje PlaybackState.
Aktualizacja PlaybackState przez setPlaybackState() natychmiast powiadamia wszystkie podłączone MediaController. Systemowe centrum multimedialne, urządzenie Bluetooth i Android Auto otrzymują aktualizację jednocześnie — opóźnienie nie przekracza 50 ms w normalnych warunkach.
PlaybackState zawiera kluczowe flagi stanu: isPlaying, pozycję, prędkość, dostępne akcje (play, pause, seek, stop). Bez prawidłowo wypełnionego PlaybackState system nie wie, jakie polecenia obsługuje aplikacja i nie wysyła odpowiednich zdarzeń.
Metadane (MediaMetadata) uzupełniają stan informacją o bieżącym utworze — title, artist, album art URI. Android Auto i urządzenia noszone używają MediaMetadata do wyświetlania informacji na ekranie. Według Google I/O 2024, prawidłowe wypełnienie MediaMetadata zwiększa widoczność aplikacji w zewnętrznych launcherach o 40%.
Architektura MediaSession składa się z czterech wzajemnie powiązanych komponentów, z których każdy rozwiązuje swoje zadanie. Deweloper musi zaimplementować wszystkie cztery dla pełnej integracji z systemem.
Sesja jest tworzona w onCreate serwisu lub Activity przez wywołanie MediaSessionCompat(context, tag). Po utworzeniu należy koniecznie wywołać setFlags(FLAG_HANDLES_MEDIA_BUTTONS | FLAG_HANDLES_TRANSPORT_CONTROLS). W onDestroy wywołuje się release() w celu zwolnienia zasobów systemowych.
Nieprawidłowe zarządzanie cyklem życia to jedna z częstych błędów. Jeśli nie wywoła się release(), sesja pozostaje w systemie, a następna aplikacja może otrzymać fałszywy stan. Android 13+ wyświetla ostrzeżenie w Logcat przy wyciekach sesji.
Podstawowa integracja zaczyna się od utworzenia sesji i implementacji Callback. Zaleca się używanie MediaSessionCompat z biblioteki AndroidX media, która zapewnia jednolity API dla wszystkich wersji Androida — 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()
}
}
W przykładzie tworzona jest MediaSession z tagiem MusicService i flagami do obsługi przycisków multimedialnych. Callback implementuje onPlay i onPause, aktualizując PlaybackState. Metoda setActions deklaruje dostępne akcje, które system wyświetla na ekranie blokady i w centrum multimedialnym.
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)
}
Metadane powinny być aktualizowane przy każdej zmianie utworu. System używa METADATA_KEY_TITLE i METADATA_KEY_ARTIST do wyświetlania informacji na wyświetlaczach Bluetooth samochodów i urządzeń noszonych. Jeśli nie ustawi się URI okładki, odtwarzacz będzie pokazywał szary placeholder.
Zestawy słuchawkowe Bluetooth wysyłają polecenia poprzez profil AVRCP 1.6+. Android transmituje te polecenia do intentów ACTION_MEDIA_BUTTON, które są przechwytywane przez MediaSession przy ustawionej fladze FLAG_HANDLES_MEDIA_BUTTONS.
Gdy użytkownik naciska przycisk Play na słuchawkach Bluetooth, system tworzy KeyEvent z kodem KEYCODE_MEDIA_PLAY, który jest dispatchowany do metody onMediaButtonEvent Callbacka. Jeśli w Callbacku zaimplementowano onPlay(), system wywołuje go bezpośrednio. Przy pojedynczym naciśnięciu przycisku na zestawie słuchawkowym wysyłany jest KEYCODE_MEDIA_PLAY_PAUSE — odtwarzacz powinien przełączać stan.
Nowoczesne słuchawki Bluetooth mogą mieć do 5 przycisków: głośność +/-, play/pause, next, previous. Każdy przycisk generuje własny KeyEvent, który powinien być poprawnie obsługiwany przez Callback. Podwójne naciśnięcie play/pause jest zwykle interpretowane jako przejście do następnego utworu (ACTION_SKIP_TO_NEXT) na wielu słuchawkach.
Według Android Compatibility Definition Document (2026), wszystkie aplikacje z treściami multimedialnymi są zobowiązane do poprawnej obsługi KEYCODE_MEDIA_PLAY_PAUSE. Ignorowanie tego wymogu prowadzi do automatycznego obniżenia oceny aplikacji w Google Play dla kategorii Muzyka i Audio.
Począwszy od Androida 11, systemowe centrum multimedialne (Media Control Panel) wyświetla do 5 ostatnich MediaSession w panelu powiadomień. Użytkownik może zarządzać odtwarzaczem bez otwierania aplikacji. Do poprawnego wyświetlania konieczne jest zaimplementowanie MediaBrowserService i prawidłowe wypełnianie PlaybackState.
Media Control Panel pokazuje: tytuł utworu, wykonawcę, okładkę (z MediaMetadata), przyciski sterowania (z dozwolonych akcji PlaybackState). Jeśli aplikacja nie aktualizuje PlaybackState przynajmniej raz na 10 sekund podczas aktywnego odtwarzania, centrum multimedialne ukrywa sesję z panelu.
private fun startForegroundService() {
val notification = NotificationCompat.Builder(this, "media_channel")
.setSmallIcon(R.drawable.ic_play)
.setContentTitle("Teraz gra")
.setContentText(currentTrackTitle)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setStyle(
androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(mediaSession.sessionToken)
)
.build()
startForeground(1001, notification)
}
Powiadomienie MediaStyle jest powiązane z MediaSession poprzez sessionToken i wyświetla standardowe przyciski multimedialne. Bez MediaStyle powiadomienie będzie wyglądać jak zwykły alert bez przycisków sterowania. Android 13+ wymaga jawnego zezwolenia POST_NOTIFICATIONS do wyświetlania.
Często zadawane pytania
Technicznie tak, ale w danym momencie tylko jedna sesja jest uważana za aktywną. Przy tworzeniu nowej sesji bez wywołania setActive(true) poprzednia pozostaje aktywna. Zaleca się posiadanie jednej sesji na aplikację lub na każde niezależne źródło audio z przełączaniem stanu aktywnego.
MediaSession nie zarządza Audio Focus automatycznie — to osobny mechanizm. Po otrzymaniu polecenia onPlay programista samodzielnie żąda AudioFocus przez AudioManager, a przy utracie fokusu wstrzymuje odtwarzanie przez sesję.
Sprawdź ustawienie flag FLAG_HANDLES_MEDIA_BUTTONS i FLAG_HANDLES_TRANSPORT_CONTROLS. Upewnij się również, że sesja jest aktywna (setActive(true)). Na Android 12+ przyciski multimedialne działają tylko przez MediaSession — stary registerMediaButtonEventReceiver nie jest obsługiwany.
Do podstawowej obsługi przycisków — nie. Ale do integracji z Android Auto, Wear OS i systemowym centrum multimedialnym wymagany jest MediaBrowserService. Google zaleca implementowanie MediaBrowserService we wszystkich aplikacjach z długotrwałym odtwarzaniem audio.
Użyj polecenia adb shell dumpsys media_session do przeglądania aktywnych sesji, ich Callback i PlaybackState. Narzędzie pokaże wszystkie zarejestrowane sesje z tagiem, aktywnością i ostatnim znanym stanem — wygodne narzędzie do debugowania.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również