MediaSession — kluczowe pojęcia, integracja i mechanizm działania w Androidzie

Autor: IT Sectr Opublikowano: 2026-05-23 Czas czytania: 8 min

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 — centralny komponent do zarządzania strumieniami multimedialnymi w Androidzie, przyjmujący polecenia z zewnętrznych źródeł.
  • Obsługuje Bluetooth AVRCP, zestawy słuchawkowe, Android Auto, urządzenia noszone i centrum multimedialne Androida.
  • Sesja synchronizuje stan odtwarzacza (play/pause/next/previous) i metadane (tytuł, wykonawca, okładka) z systemem.
  • Do działania wymaga MediaSessionCompat z AndroidX, zapewniającego wsteczną kompatybilność aż do API 14.
  • System callback MediaSession.Callback przetwarza przychodzące polecenia i zmienia stan MediaSession.

Czym jest MediaSession?

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ą.

MediaSession i MediaBrowserService

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.

Jak działa MediaSession

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 i jego metadane

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%.

Kluczowe komponenty MediaSession

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.

  • MediaSessionCompat — główna klasa sesji, tworzona z tagiem aplikacji i przyjmująca PendingIntent dla przycisków multimedialnych.
  • MediaSession.Callback — handler poleceń. Implementuje onPlay, onPause, onSkipToNext, onSeekTo i inne metody.
  • PlaybackStateCompat — bieżący stan odtwarzacza. Zawiera flagi, pozycję, prędkość i listę dostępnych akcji.
  • MediaMetadataCompat — metadane bieżącego nośnika: tytuł, wykonawca, album, okładka, czas trwania.

Cykl życia MediaSession

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.

Integracja MediaSession w aplikacji

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.

Tworzenie MediaSession i 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()
    }
}

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.

Ustawianie 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)
}

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.

Obsługa poleceń multimedialnych z Bluetooth i słuchawek

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.

Obsługa złożonych scenariuszy z wieloma przyciskami

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.

Synchronizacja z systemowym centrum multimedialnym

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.

Foreground-service z powiadomieniem

kotlin
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

Czy aplikacja może mieć kilka aktywnych MediaSession jednocześnie?

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.

Jak MediaSession współdziała z Audio Focus?

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ę.

Dlaczego przyciski multimedialne na słuchawkach nie działają z moją aplikacją?

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.

Czy MediaBrowserService jest wymagany do działania MediaSession?

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.

Jak sprawdzić, czy MediaSession jest prawidłowo skonfigurowana?

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

  • MediaSession — standardowy sposób zarządzania odtwarzaniem w Androidzie, zastępujący RemoteControlClient począwszy od API 21.
  • Sesja przyjmuje polecenia z Bluetooth, słuchawek, Android Auto i systemowego centrum multimedialnego poprzez system callback.
  • PlaybackState i MediaMetadata — dwa obowiązkowe komponenty do poprawnej synchronizacji z systemowym UI.
  • Integracja jest wykonywana przez MediaSessionCompat z AndroidX media, zapewniający kompatybilność z API 14+.
  • Do wyświetlania w systemowym centrum multimedialnym wymagany jest MediaBrowserService i foreground-service z powiadomieniem MediaStyle.
  • Obsługa Audio Focus — osobne zadanie, nieautomatyzowane przez MediaSession. Programista zarządza fokusem samodzielnie.
  • Do debugowania użyj adb shell dumpsys media_session do przeglądania aktywnych sesji i ich stanu.

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.

Omów projekt

Przeczytaj również