Understanding MediaSession (Part 4/4)
How to use it for complex use cases
The goal of this series of articles is to give you a deep understanding of
MediaSession, what it is good for, when to use it, and when not to. This is the final part of a 4 part series that includes:
- Is MediaSession for me?
- Making sense of the complex media landscape
- How to use it for simple use cases
- How to use it for complex use cases (this article)
App that plays audio in the background
The diagram below provides a high level overview of all the different components that you have to implement in order to create an audio playback app that uses
MediaBrowserService to play audio in the background.
Please refer to developers.android.com to get more details on each of the classes that you will need to use. At a high level you will have to:
- Service — Create a
Servicethat manages the player and handles preparing and playing media. Create
MediaStylenotifications that are tied to this service. This service needs to extend
MediaBrowserServicein order to provide content (eg: this is how Android Auto can browse the content provided by the app). The details for the service are provided in the sections below.
- Client — Create an
Fragmentthat connects to this service using
MediaBrowserallows access to the content provided by the
Service, and allows the use of
MediaSessionto control playback and get updates on what media is loaded and the playback state changes (which actually occur in your
Service). The details for the client are provided in the sections below.
The following diagram takes a closer look at the
Service that you will need to have in your app that manages your player (
ExoPlayer), and to create the
MediaSession and keep it up to date with your player’s state changes. At a high level you will have to:
onCreate()you have to create a
MediaSessionand get it’s token.
- Pass this token to the
setSessionToken, and this will connect the
MediaSession, and will allow the
MediaBrowser(client to work with the
- The most important callback to implement is
MediaSession.Callback. This callback is what allows transport controls to invoke play, stop, pause, etc actions on the callback, which are then used to play, stop, pause the underlying player.
- You will have to extend the
MediaBrowserServiceand implement two methods in order to expose the catalog of media content that you are making browsable —
Note: If you don’t need your content to be browsed by Android Auto, or other apps outside of your app’s UI, then you are safe to remove
MediaBrowserService in your
MediaBrowser in your client code). In this case, just by using
MediaSession, you are getting all the benefits of allowing other apps to control playback and report state changes, without the ability to browse content in your app from outside your app’s UI.
Activity / Client / UI code
The following diagram takes a closer look at the client side code that you will need to have in your app in order to integrate with
MediaBrowser. At a high level you will have to:
- In the
onStart()method of your
Activity, use a
MediaBrowserto connect to the
Service. This will allow you to get content that you can browse in the UI of your app, and playback using the
TransportControlsyou get from the
MediaController. Note that you have to get the
MediaSessiontoken from the
MediaBrowser, in order to correctly connect your
- You have to implement three callbacks in your
MediaController.Callback— this is used to update the of your app with the current playback state, and what media is currently loaded.
MediaBrowser.ConnectionCallback— this is used to get the
MediaSessiontoken. You can then get the
TransportControlsthat you will use to actually initiate playback, pause, stop, skip, etc.
MediaBrowser.SubscriptionCallback— this is used to update your UI so that you can show the user content (from the
Service) that they can browse for playback.