MediaSession — komponent i Android-ramverket för hantering av mediainnehållsuppspelning och integration med externa enheter. Det ger ett enhetligt gränssnitt för interaktion med Bluetooth-headsets, hörlurar, Android Auto och systemets mediecenter. Enligt Android Developers Guide, 2026 ersätter MediaSession den föråldrade RemoteControlClient och är obligatorisk för spelare som synkroniserar med systemet.
Huvudpunkter
MediaSession — är en systemkomponent i Android som låter en app deklarera sin mediaaktivitet och ta emot kontrollkommandon utifrån. När användaren trycker på Play-knappen på ett Bluetooth-headset, överför systemet denna händelse till den aktiva MediaSession, och appen reagerar via sin egen Callback.
Före Android 5.0 användes RemoteControlClient för dessa ändamål, men den gav inte den nödvändiga flexibiliteten och stödde inte moderna scenarier — Android Auto, smarta klockor, smarta högtalare. MediaSession introducerades i API 21 och blev de facto-standarden för alla Android-appar med ljud- och videouppspelning.
Enligt Android Developer Documentation (2026) bör appen skapa en MediaSession för varje oberoende uppspelningskälla. Det kan bara finnas en aktiv session åt gången — varje ny session avaktiverar automatiskt den föregående.
Kombinationen av MediaSession med MediaBrowserService ger en komplett mediehanteringscykel: tjänsten tillhandahåller ett innehållsträd (spellistor, kataloger) och sessionen tar emot navigerings- och uppspelningskommandon. Detta är den arkitektur som Google rekommenderar för musikspelare, poddar och ljudböcker.
MediaBrowserService körs som en foreground-tjänst med en notifiering, vilket garanterar att appen fungerar även efter att Activity har avslutats. Detta är avgörande för ljudspelare som måste fortsätta spela när appen är minimerad.
Sessionen stöder två typer av interaktion: den tar emot kommandon från MediaController (klientsidan) och sänder tillstånd via PlaybackState. MediaController kan finnas i samma process eller i en separat app — systemet dirigerar förfrågningar via SessionToken.
När användaren anropar Android-röstassistenten och säger “Spela nästa låt”, hittar systemet den aktiva MediaSession genom kopplingen till MediaBrowserService och skickar kommandot ACTION_SKIP_TO_NEXT. Appens Callback får anropet onSkipToNext() och uppdaterar PlaybackState.
Uppdatering av PlaybackState via setPlaybackState() meddelar omedelbart alla anslutna MediaController. Systemets mediecenter, Bluetooth-enheten och Android Auto får uppdateringen samtidigt — fördröjningen överstiger inte 50 ms under normala förhållanden.
PlaybackState innehåller viktiga tillståndsflaggor: isPlaying, position, hastighet, tillgängliga åtgärder (play, pause, seek, stop). Utan korrekt ifylld PlaybackState vet systemet inte vilka kommandon appen stöder och skickar inte motsvarande händelser.
Metadata (MediaMetadata) kompletterar tillståndet med information om den aktuella låten — title, artist, album art URI. Android Auto och bärbara enheter använder MediaMetadata för att visa information på skärmen. Enligt Google I/O 2024 ökar korrekt ifyllnad av MediaMetadata appens synlighet i tredjepartsstartare med 40%.
Arkitekturen för MediaSession består av fyra sammankopplade komponenter, var och en löser sin egen uppgift. Utvecklaren måste implementera alla fyra för full integration med systemet.
Sessionen skapas i onCreate för tjänsten eller Activity genom att anropa MediaSessionCompat(context, tag). Efter skapandet måste man anropa setFlags(FLAG_HANDLES_MEDIA_BUTTONS | FLAG_HANDLES_TRANSPORT_CONTROLS). I onDestroy anropas release() för att frigöra systemresurser.
Felaktig hantering av livscykeln är ett vanligt misstag. Om release() inte anropas, stannar sessionen kvar i systemet och nästa app kan få ett falskt tillstånd. Android 13+ visar en varning i Logcat vid sessionsläckor.
Grundläggande integration börjar med att skapa sessionen och implementera Callback. Det rekommenderas att använda MediaSessionCompat från AndroidX media-biblioteket, som ger ett enhetligt API för alla Android-versioner — från API 14 till 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()
}
}
I exemplet skapas en MediaSession med taggen MusicService och flaggor för att hantera mediaknappar. Callback implementerar onPlay och onPause, och uppdaterar PlaybackState. Metoden setActions deklarerar tillgängliga åtgärder som systemet visar på låsskärmen och i mediecentret.
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 bör uppdateras vid varje låtbyte. Systemet använder METADATA_KEY_TITLE och METADATA_KEY_ARTIST för att visa information på Bluetooth-skärmar i bilar och bärbara enheter. Om omslags-URI inte anges, visar spelaren en grå placeholder.
Bluetooth-headsets skickar kommandon via profilen AVRCP 1.6+. Android överför dessa kommandon till ACTION_MEDIA_BUTTON-intenter, som fångas upp av MediaSession när flaggan FLAG_HANDLES_MEDIA_BUTTONS är inställd.
När användaren trycker på Play-knappen på Bluetooth-hörlurar, skapar systemet en KeyEvent med koden KEYCODE_MEDIA_PLAY, som skickas till Callbackens onMediaButtonEvent-metod. Om onPlay() är implementerad i Callback, anropar systemet den direkt. Vid enkel tryckning på headset-knappen skickas KEYCODE_MEDIA_PLAY_PAUSE — spelaren bör växla tillstånd.
Moderna Bluetooth-hörlurar kan ha upp till 5 knappar: volym +/-, play/pause, next, previous. Varje knapp genererar sin egen KeyEvent som måste bearbetas korrekt av Callback. Dubbeltryck på play/pause tolkas vanligtvis som att hoppa till nästa låt (ACTION_SKIP_TO_NEXT) på många hörlurar.
Enligt Android Compatibility Definition Document (2026) är alla appar med mediainnehåll skyldiga att korrekt bearbeta KEYCODE_MEDIA_PLAY_PAUSE. Att ignorera detta krav leder till automatisk sänkning av appbetyget i Google Play för kategorin Musik och Ljud.
Från och med Android 11 visar systemets mediecenter (Media Control Panel) upp till 5 senaste MediaSession i notifieringspanelen. Användaren kan styra spelaren utan att öppna appen. För korrekt visning krävs implementering av MediaBrowserService och korrekt ifyllnad av PlaybackState.
Media Control Panel visar: låtens titel, artist, omslag (från MediaMetadata), kontrollknappar (från PlaybackState tillåtna åtgärder). Om appen inte uppdaterar PlaybackState minst en gång var 10:e sekund under aktiv uppspelning, döljer mediecentret sessionen från panelen.
private fun startForegroundService() {
val notification = NotificationCompat.Builder(this, "media_channel")
.setSmallIcon(R.drawable.ic_play)
.setContentTitle("Spelar nu")
.setContentText(currentTrackTitle)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setStyle(
androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(mediaSession.sessionToken)
)
.build()
startForeground(1001, notification)
}
MediaStyle-notifieringen kopplas till MediaSession via sessionToken och visar standardmediaknappar. Utan MediaStyle kommer notifieringen att se ut som en vanlig varning utan kontrollknappar. Android 13+ kräver explicit tillstånd POST_NOTIFICATIONS för visning.
Vanliga frågor
Tekniskt sett ja, men vid en given tidpunkt anses endast en session vara aktiv. när en ny session skapas utan att anropa setActive(true) förblir den föregående aktiv. Det rekommenderas att ha en session per app eller per oberoende ljudkälla med växling av aktivt tillstånd.
MediaSession hanterar inte Audio Focus automatiskt — detta är en separat mekanism. Vid mottagning av kommandot onPlay begär utvecklaren själv AudioFocus via AudioManager, och vid förlust av fokus pausar uppspelningen via sessionen.
Kontrollera inställningen av flaggorna FLAG_HANDLES_MEDIA_BUTTONS och FLAG_HANDLES_TRANSPORT_CONTROLS. Se också till att sessionen är aktiv (setActive(true)). På Android 12+ fungerar mediaknappar endast via MediaSession — den gamla registerMediaButtonEventReceiver stöds inte.
För grundläggande knapphantering — nej. Men för integration med Android Auto, Wear OS och systemets mediecenter krävs MediaBrowserService. Google rekommenderar att implementera MediaBrowserService i alla appar med långvarig ljuduppspelning.
Använd kommandot adb shell dumpsys media_session för att visa aktiva sessioner, deras Callback och PlaybackState. Verktyget visar alla registrerade sessioner med tagg, aktivitet och senast kända tillstånd — ett bekvämt verktyg för felsökning.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också