It is often desirable to play media while an app is not in the foreground. For example, a music player generally keeps playing music when the user has locked their device or is using another app. The Media3 library provides a series of interfaces that allow you to support background playback.
Use a MediaSessionService
To enable background playback, you should contain the Player
and
MediaSession
inside a separate Service.
This allows the device to continue serving media even while your app is not in
the foreground.

MediaSessionService
allows the media
session to run separately from the app's activityWhen hosting a player inside a Service, you should use a MediaSessionService
.
To do this, create a class that extends MediaSessionService
` and create your
media session inside of it.
Using MediaSessionService
makes it possible for external clients like Google
Assistant, system media controls, or companion devices like Wear OS to discover
your service, connect to it, and control playback, all without accessing your
app's UI activity at all. In fact, there can be multiple client apps connected
to the same MediaSessionService
at the same time, each app with its own
MediaController
.
Provide access to the media session
Override the onGetSession()
method to give other clients access to your media
session.
Kotlin
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // If desired, validate the controller before returning the media session override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? = mediaSession // Create your player and media session in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaSession = MediaSession.Builder(this, player).build() } // Remember to release the player and media session in onDestroy override fun onDestroy() { mediaSession?.run { player.release() release() mediaSession = null } super.onDestroy() } }
Java
public class PlaybackService extends MediaSessionService { private MediaSession mediaSession = null; @Override public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) { // If desired, validate the controller before returning the media session return mediaSession; } // Create your Player and MediaSession in the onCreate lifecycle event @Override public void onCreate() { super.onCreate(); ExoPlayer player = new ExoPlayer.Builder(this).build(); mediaSession = new MediaSession.Builder(this, player).build(); } // Remember to release the player and media session in onDestroy @Override public void onDestroy() { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; super.onDestroy(); } }
An app requires permission to run a foreground service. Add the
FOREGROUND_SERVICE
permission to the manifest, and if you target API 34 and
above also FOREGROUND_SERVICE_MEDIA_PLAYBACK
:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
You must also declare your Service
class in the manifest with an intent filter
of MediaSessionService
.
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
You must define a
foregroundServiceType
that includes mediaPlayback
when your app is running on a device with Android
10 (API level 29) and higher.
Control playback in the media session
In the Activity or Fragment containing your player UI, you can establish a link
between the UI and your media session using a MediaController
. Your UI uses
the media controller to send commands from your UI to the player within the
session. See the
Create a MediaController
guide for details on creating and using a MediaController
.
Handle UI commands
The MediaSession
receives commands from the controller through its
MediaSession.Callback
. Initializing a MediaSession
creates a default
implementation of MediaSession.Callback
that automatically handles all
commands a MediaController
sends to your player.
Notification
A MediaSessionService
automatically creates a MediaNotification
for you that
should work in most cases. By default, the published notification is a
MediaStyle
notification
that stays updated with the latest information
from your media session and displays playback controls. The MediaNotification
is aware of your session and can be used to control playback for any other apps
that are connected to the same session.
For example, a music streaming app using a MediaSessionService
would create a
MediaNotification
that displays the title, artist, and album art for the
current song playing alongside playback controls based on your MediaSession
configuration.
To provide a custom notification, create a
MediaNotification.Provider
with DefaultMediaNotificationProvider.Builder
or by creating a custom implementation of the provider interface. Add your
provider to your MediaSession
with
setMediaNotificationProvider
.