Play the sound already

I spent all day figuring out how to play a mp3 file in my Android app.  Before you start to question my programming skills (which is fine) let me add a few requirements:

1. The sound file is contained in a subdirectory within my assets

2. The code should work for external assets outside of the bundle as well as assets within the bundle.  For this reason I didn’t want to use resource ids.

3. The file should be streamed and not loaded entirely into memory.

The MediaPlayer seems like the best option to use and I immediately tried coding to that.  I spent most of the time trying to get the Uri implementation to work (ex: “file:///android_asset/sounds/music.mp3”) but that just refused to work for me.

I was able to use the AssetManager to get a AssetFileDescriptor which can give you a FileDescriptor that can be used as a data source for the MediaPlayer.

Here is the code:

// get the asset file descriptor from our context
AssetFileDescriptor afd = mContext.getAssets().openFd(filename);

// media player created in idle state (always call setDataSource next)
MediaPlayer mp = new MediaPlayer();

// setting data source puts media player into the initialized state

// setting of looping should be done in the initialized or 
// prepared state (not idle state)

// prepare required before calling start or stop methods

// listeners require running on the ui thread
mp.setOnCompletionListener(new OnCompletionListener()
    public void onCompletion(MediaPlayer mp)

// finally play it

// cleanup afd