Building a simple audio app in Android (Part 2/3)

Building the app

Introduction

The goal of this series of articles is to get you started with the Android MediaPlayer API by going thru the journey of creating a very basic audio playback application called “A Simple MediaPlayer” app. This is the second part of a 3 part series that includes:

  1. MediaPlayer introduction
  2. Building the app (this article)
  3. Synchronizing with the SeekBar

Part 2/3 — Building the app

This article will cover the following:

  • How to use the MediaPlayer class (create, prepare, start, reset, seekTo) and get a working understanding of its state machine.

What does the app look like?

Where is the source code?

The source code for the sample app is available on GitHub. This app allows you to play MP3 files from res/raw folder without streaming it from network audio sources. It exercises the MediaPlayer API so you can get a clear understanding of the states and the transitions by interacting with the app.

Building the app

The app uses the parts of the state machine described in Part 1/3 of the series. You can look at MediaPlayerHolder class of the sample app to see this in action.

  1. The MediaPlayerHolder implements an interface called PlayerAdapter which allows the MainActivity to control playback functions.
  2. The MainActivity creates a UI that allows the user to play, pause, and stop media playback. And it creates a MediaPlayerHolder object.
  3. The MainActivity implements an interface called PlaybackInfoListener which allows the MediaPlayerHolder to update it when media duration and progress changes.

Loading Media (prepare, prepareAsync)

To keep things simple, the audio files are loaded from the res/raw folder in this project. There is 1 file in this folder: jazz_in_paris.mp3.

Playback controls (start, reset, stop, seekTo)

There are only 3 buttons in the UI of the sample app — PLAY, PAUSE, RESET. Here’s the code in MainActivity related to this. Note: The mPlayerAdapter implements PlayerAdapter, and it is how MediaPlayerHolder functionality is exposed to the MainActivity.

Here are a few methods in MediaPlayerHolder (which implements PlayerAdapter) that actually manages the MediaPlayer.

MediaPlayer lifecycle

When you’re playing audio and you change your screen orientation, then there might be issues with playback. This article is just focused on MediaPlayer, and it doesn’t go into the client server architecture you would need to implement in order to handle audio playback in the background even when your app’s activities aren’t running or in the foreground.

When screen orientation changes, Android destroys the Activity and recreates it. In our sample code, we create the MediaPlayer and keep it around during the lifetime of the MainActivity. In order to keep things simple, we are going to override the default behavior of Activity to destroy itself and handle the screen configuration changes ourselves.

We do this by adding the following to the app’s AndroidManfiest.xml. You can learn more about this on developers.android.com.

It is important not to hold on to the MediaPlayer’s resources when no audio is being played back. The MediaPlayer holds lots of shared resources that are provided by the Android OS (such as codecs). And it’s really important to release these resources when not in use. The MediaPlayerHolder class has a release() method, which ends up releasing the MediaPlayer. This is called by the onStop() method of the MainActivity.

Once a MediaPlayer has been released, it can’t be used again. So a new one has to be created. The MediaPlayerHolder takes care of this, when the loadMedia(int) method is called, in order to load and prepare the MP3 file to be played from the APK.

The MainActivity does not support media playback when the app is moved to the background. In the onStop() method, playback is stopped, and the MediaPlayer is released.

In order to support playback in the background you should use a bound and started service, or use a MediaSession. We will cover each of these in other articles.

To continue building the app and integrating the SeekBar for continuous syncing of playback progress and scrubber, please checkout Part 3/3 of this series- Synchronizing with the SeekBar.

Android Media Resources

One clap, two clap, three clap, forty?

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