How to load an audio resource from an online in Android?
Audio resources like music and sound effects can enhance the user experience of Android apps. The Android framework provides the MediaPlayer class to stream and play audio files in apps. In this article, we’ll go over the key steps to load and play an audio file retrieved from an online source in an Android app using MediaPlayer.
We’ll cover how to:
- Add MediaPlayer to your app’s code
- Get the audio file from an online URL
- Set the audio URL as the MediaPlayer data source
- Prepare the MediaPlayer and start playback
- Handle playback completion
- Pause and resume playback
- Handle errors
- Release resources when done
The MediaPlayer class handles retrieving, decoding and playing audio with minimal code required. By following the steps in this guide, you’ll be able to enhance your Android app with audio playback capabilities.
Add MediaPlayer to Code
The first step is to add the MediaPlayer class to your Android project. This can be done by importing android.media.MediaPlayer at the top of your activity class:
import android.media.MediaPlayer;
Next, you need to declare a MediaPlayer variable as a class member:
private MediaPlayer mediaPlayer;
This will allow you to reference the MediaPlayer object throughout your activity.
Get Audio Resource
There are two main options for storing audio files in an Android app – the raw folder and assets folder. Here’s an overview of each:
Raw Folder
The raw folder stores raw, uncompressed audio files. Placing resources here ensures they are bundled and accessible at runtime. To load an audio file from raw, use getResources().openRawResource() and pass the R.raw.[filename] resource:
Resources res = getResources(); InputStream audioStream = res.openRawResource(R.raw.my_audio_file);
Assets Folder
The assets folder stores compressed audio files such as MP3s. To access assets, use AssetManager:
AssetManager assets = getAssets(); InputStream audioStream = assets.open("my_audio_file.mp3");
The assets folder is useful for bundling audio files you want to ship with the app while saving space compared to raw. Overall, raw is simpler while assets allows compression.
Set MediaPlayer DataSource
Once you have initialized the MediaPlayer, the next step is to set the data source which contains the audio file. This is done by calling the setDataSource() method on the MediaPlayer instance.
The setDataSource() method accepts either a file path to the audio file as a String, or an InputStream object. For example:
mediaPlayer.setDataSource("/sdcard/music/sample.mp3"); //for file path or InputStream is = getResources().openRawResource(R.raw.sample); mediaPlayer.setDataSource(is); //for InputStream
This loads the audio file into the MediaPlayer ready for playback.
It’s important to call setDataSource() before calling prepare() or prepareAsync() on the MediaPlayer. The datasource needs to be set first to indicate the audio content you want to play.
Also note that for audio files bundled with your app, you can load them through a raw resource id rather than an absolute file path.
Prepare and Start
Before starting playback of the audio, the MediaPlayer needs to be prepared by calling the prepare() method. This preloads the audio resource and gets the MediaPlayer ready to play the audio.
For example:
mediaPlayer.prepare();
Calling prepare() can be a lengthy operation, so it should be done on a background thread to avoid blocking the UI thread.
Once prepare() completes successfully, start() can be called on the MediaPlayer to begin playback:
mediaPlayer.start();
The start() method begins playing the audio resource from the beginning. The audio will continue playing until it completes, an error occurs, or the stop() method is called.
So in summary, prepare() preloads the audio resource to get it ready for playback, and start() begins actively playing the audio. Calling prepare() before start() is crucial to ensure the MediaPlayer is ready and to avoid errors.
Handle Completion
Once the audio file finishes playing, you’ll want to stop the MediaPlayer and reset it so it’s ready to play again if needed. This can be done by setting an OnCompletionListener on the MediaPlayer.
The OnCompletionListener will get triggered when the end of the media source is reached during playback. Inside the onCompletion() method is where you should put logic to stop the player, reset the position to 0, and perform any other steps needed to clean things up.
For example:
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.stop();
mp.reset();
mp.release();
}
});
Stopping the player will end playback. Resetting will clear out any buffered data and reset the playback position to 0 so it’s ready for the next play invocation. Releasing the resources will free up anything taken up by the MediaPlayer so that memory can be reclaimed.
Having this listener setup allows your app to properly finish each playback cycle and start fresh when audio is played again.
Pause and Resume
The MediaPlayer class provides methods to pause and resume playback of audio files. This allows your app to stop playing an audio file temporarily and resume from the same point later.
To pause playback, call the pause()
method on your MediaPlayer instance. This will pause the audio playback and freeze at the current position. Later when you want to resume playback, call the start()
method.
For example:
mediaPlayer.pause(); // pause playback
// do other work
mediaPlayer.start(); // resume playback
An important thing to note is that you need to store the playback state when pausing. This is required so that when resuming, the MediaPlayer knows the correct position to start playing from.
To save the playback state, you can use getCurrentPosition()
to get the current playback position in milliseconds. Store this value before calling pause(). Later when resuming, you can seek to that position by using seekTo()
before calling start().
For example:
int pausePosition = mediaPlayer.getCurrentPosition();
mediaPlayer.pause();
// do other work
mediaPlayer.seekTo(pausePosition);
mediaPlayer.start();
This will allow your app to properly resume audio playback from the correct position after a pause.
Handle Errors
When loading and playing audio, errors may occur that you need to handle gracefully in your app. The main way to do this is by using try/catch blocks:
<try>
// Code that may cause an error
</try>
<catch>(Exception e)</catch>
This will catch any exceptions thrown in the try block. For audio resources, some common exceptions to handle include:
- IOException – if there is an error loading/reading the audio file
- IllegalArgumentException – if the audio URI is invalid
- IllegalStateException – if called incorrectly, like before prepare()
When you catch an error, you should display a graceful error message to the user rather than crashing the app. For example:
Toast.makeText(this, "Error playing audio: " + e.getMessage(), Toast.LENGTH_SHORT).show();
Properly handling errors ensures your app doesn’t crash and provides a good user experience.
Release Resources
After you are done playing the audio file, it is important to properly release the resources that were allocated for the MediaPlayer. Failure to do so can result in resource leaks and other issues.
To release the resources, simply call the release() method on the MediaPlayer when you are completely done with it:
mediaPlayer.release();
This will de-allocate the resources used by the MediaPlayer object. It is especially important to call release() when the activity or fragment containing the MediaPlayer is destroyed.
Some key points on releasing MediaPlayer resources:
- Call release() when the MediaPlayer is no longer needed.
- Make sure to call release() to avoid resource leaks.
- Release the MediaPlayer before the containing Activity or Fragment is destroyed.
- After release() is called, the MediaPlayer object can no longer be used.
By properly releasing resources when they are no longer needed, you can avoid issues like running out of memory or having too many open files.
Recap and Summary
In this article, we covered the key steps for loading and playing an audio resource from an online source in an Android app:
- Adding MediaPlayer to our code
- Getting a reference to the audio file URL
- Setting the MediaPlayer data source
- Preparing MediaPlayer and starting playback
- Handling playback completion
- Pausing and resuming audio
- Handling errors gracefully
- Releasing resources when done
Learning to load and play audio can enrich your Android app user experience. With audio capabilities, you can stream podcasts, play sound effects, add background music, and more. This creates more dynamic and engaging apps.
Next learning steps for readers could include:
- Adding audio playback controls like play/pause buttons
- Implementing seekbars for track scrubbing
- Supporting playlists of audio files
- Handling audio focus
- Saving playback position
- Downloading audio for offline playback
With the core concepts covered here, you have the foundation to build immersive audio experiences in your Android apps.