FIGURE 1
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.
Figure 1: The MediaSessionService allows the media session to run separately from the app's activity
When 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.
You need to implement three lifecycle methods of your service:
onCreate() is called when the first controller is about to connect and the service is instantiated and started. It's the best place to build Player and MediaSession.
onTaskRemoved(Intent) is called when the user dismisses the app from the recent tasks. If playback is ongoing, the app can choose to keep the service running in the foreground. If the player is paused, the service is not in the foreground and needs to be stopped.
onDestroy() is called when the service is being stopped. All resources including player and session need to be released.
JAVA
public class PlaybackService extends MediaSessionService {
private MediaSession mediaSession = null;
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
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();
}
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>