Playing MP3 file in Android App (Java)
PART 1. Using MediaPlayer for playing MP3 file. Requesting Audio Focus. Releasing System resources.
You are developing an android app with Android Studio, and you want it to play MP3 file. Here you find step by step directions how to do it.
STEP 1
Let’s put our file in the right place. We need to create new directory. Right click on res folder then navigate to Android Resource Directory.
Clicking on Android Resource Directory brings up a pop up menu:
In Resource type make a selection of raw. Observe, the Directory name changing to raw.
Click OK.
Directory raw is created.
Our MP3 file needs to be in this directory. Move the file in question to newly created raw directory. My preferred way of doing it is to open the raw directory in Finder(Mac) or File Explore(Windows) and then just drop my file there.
STEP 2
For handling MP3 files Android has inbuilt class MediaPlayer, we will need to have a reference variable for the object of this class.
Several apps can output audio at the same, in order to avoid it Android has the concept of audio focus. If the app wants to play audio, it has to request audio focus. However, another app might request and acquire focus. Our app has to be able to handle this. Objects of AudioManager class are responsible for handling audio focus. We need to have a reference variable for the object of class AudioManager.
To ensure encapsulation, we should make our reference variables private:
/** Handles playback of all the sound files */
private MediaPlayer mMediaPlayer;
/** Handles audio focus when playing a sound file */
private AudioManager mAudioManager;
STEP 3
Media Player consumes valuable system resources, so it is important not to hang on it longer than nessary. Let’s create the releaseMediaPlayer() method which would be responsible for cleaning up media player by releasing its resources. We are going to check if our media player is not a null, if it is not it might be playing. Regardless of the state of the media player, we will release it and set the reference to null to mark that it is ready for garbage collection. This is going to be our releaseMediaPlayer() method for now:
/**
* Clean up the media player by releasing its resources.
*/
private void releaseMediaPlayer() {
// If the media player is not null, then it may be currently playing a sound.
if (mMediaPlayer != null) {
// Regardless of the current state of the media player, release its resources
// because we no longer need it.
mMediaPlayer.release();
// Set the media player back to null. For our code, we've decided that
// setting the media player to null is an easy way to tell that the media player
// is not configured to play an audio file at the moment.
mMediaPlayer = null;
}
}
STEP 4
We need to override the onStop() of Android Activity Life cycle. The onStop() method is good for cleaning up all your activities’ resources, and a good place to clean up after using resources for MediaPlayer.
@Override
protected void onStop() {
super.onStop();
releaseMediaPlayer();
}
STEP 5
We will need to create two listeners. One is for capturing the event when our MP3 file finishes playing and another one is going to be responsible for capturing the change in audio focus.
MediaPlayer.OnCompletiotionListener is a functional interface that has one abstract method onCompletion , where we are going to release our media player. Below is the listener for when is our MP3 done playing.
private MediaPlayer.OnCompletionListener mCompletitionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
releaseMediaPlayer();
}
};
Lets work on the listener that gets triggered when we get or loose audio focus. AudioManager.OnAudioFocusChangeListener is a functional interface with one abstract method onAudioFocusChange. The parameter to onAudioFocusChange method is focusChange, constant integer value that indicates whether the focus was gained, lost, transient, or going be held for some time. When we loose focus for a short time, we pause our player. If we gain audio focus, we start playing our MP3, and when we loose our audio focus, we release our player.
private AudioManager.OnAudioFocusChangeListener mOnAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
mMediaPlayer.pause();
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
mMediaPlayer.start();
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
length = mMediaPlayer.getCurrentPosition();
Log.d("loss focus", "loss of focus");
releaseMediaPlayer();
}
}
};
STEP 6
We are going to add one more line to releaseMediaPlayer method that would allow us to abandon audio focus, independent on whether we were granted it . This would also unregister the AudioFocusChangeListener, so we don’t have anymore callbacks.
/**
* Clean up the media player by releasing its resources.
*/
private void releaseMediaPlayer() {
// If the media player is not null, then it may be currently playing a sound.
if (mMediaPlayer != null) {
// Regardless of the current state of the media player, release its resources
// because we no longer need it.
mMediaPlayer.release();
// Set the media player back to null. For our code, we've decided that
// setting the media player to null is an easy way to tell that the media player
// is not configured to play an audio file at the moment.
mMediaPlayer = null;
// Regardless of whether or not we were granted audio focus, abandon it. This also
// unregisters the AudioFocusChangeListener so we don't get anymore callbacks.
mAudioManager.abandonAudioFocus(mOnAudioFocusChangeListener);
}
}
STEP 7
Now for the final step, we are going to put things together in onCreate method. We request access of Android system-level services with getSystemServices method, passing Context.AUDIO_SERVICE. We will need to cast into AudioManager, because this method returns an object.
Using the instance of AudioManager we request audio focus for unknown duration with requestAudioFocus method. Upon successful gain of audio focus, we create our media player with create method, start our playback, and attach mCompletiotionListener that we created in STEP 5.
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
/* Request audio focus so in order to play the audio file. The app needs to play a
audio file, so we will request audio focus for unknown duration
with AUDIOFOCUS_GAIN*/
int result = 0;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
//for API >= 26
result = mAudioManager.requestAudioFocus((new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)).build());
} else {
result = mAudioManager.requestAudioFocus(mOnAudioFocusChangeListener,AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
//create player
mMediaPlayer = MediaPlayer.create(this, R.raw.play_file);
//start playing
Log.d("OnCreate method", "OnCreate player created");
mMediaPlayer.start();
//listen for completition of playing
mMediaPlayer.setOnCompletionListener(mCompletitionListener);
}
Take aways:
MediaPlayer is the class that could be used for MP3 file. Your application should request audio focus for playing MP3 file, it should be accomplished with the help of AudioManager class. You should release your media player as soon as you are done with it.
Happy coding, my friends!
You can find all the code here: