Understanding MediaSession (Part 4/4)

How to use it for complex use cases

Introduction

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:

  1. Is MediaSession for me?
  2. Making sense of the complex media landscape
  3. How to use it for simple use cases
  4. 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 MediaSession and 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 Service that manages the player and handles preparing and playing media. Create MediaStyle notifications that are tied to this service. This service needs to extend MediaBrowserService in 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 Activity or Fragment that connects to this service using MediaBrowser. MediaBrowser allows access to the content provided by the Service, and allows the use of MediaSession to 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.

Service code

The following diagram takes a closer look at the Service that you will need to have in your app that manages your player (MediaPlayer or 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:

  • In onCreate() you have to create a MediaSession and get it’s token.
  • Pass this token to the MediaBrowserService by calling setSessionToken, and this will connect the MediaBrowserService to the MediaSession, and will allow the MediaBrowser (client to work with the MediaSession).
  • 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 MediaBrowserService and implement two methods in order to expose the catalog of media content that you are making browsable — onGetRoot() and onLoadChildren().

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 Service (and 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 MediaSession and MediaBrowser. At a high level you will have to:

  • In the onStart() method of your Activity, use a MediaBrowser to 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 TransportControls you get from the MediaSession’s MediaController. Note that you have to get the MediaSession token from the MediaBrowser, in order to correctly connect your TransportControls to the MediaSession.
  • You have to implement three callbacks in your Activity
  • 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 MediaController using the MediaBrowser’s MediaSession token. You can then get the TransportControls that 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.
One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.