1
votes

Here is my source code

private MediaPlayer mP;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mP = MediaPlayer.create(getApplicationContext(),R.raw.nintendo);
}

@Override
protected void onResume() {

    super.onResume();
    try {

        mP.prepareAsync();
    } catch (IllegalStateException e) {

        e.printStackTrace();
    }
    mP.setOnPreparedListener(new OnPreparedListener() {

        @Override
        public void onPrepared(MediaPlayer mp) {

            mP.seekTo(0);
            mP.start();
        }
    });
}

@Override
protected void onPause() {

    super.onPause();
    mP.stop();
    mP.release();
}

Here is what I get in Logcat when i try running this enter image description hereenter image description here

Line 64: mP.stop();

This Logcat output occurs when i do this following sequence, Launch -> Homescreen->Go back to app -> Homescreen

Now I know that the IllegalStateException occurs when you try to do an invalid state change. From, http://developer.android.com/reference/android/media/MediaPlayer.html, I know that a valid state change would be from "start to stop" or "stop to stop". I thought the logic I have in my code represents a valid state change though(from start in onPause to stop/release in onPause). I debugged a bit further and realized that after i went to the homescreen and back to the app, onPrepared was not getting called.... I didn't understand this either because I called mP.prepareAsync() before hand(asynchronous to avoid blocking this main ui thread) before hand. Shouldn't onPrepared be triggered after all the sound resources have been gathered?

I checked out a few other threads Couldn't be this one Android Media Player because I constructed the MediaPlayer fine. And again here android MediaPlayer not playing mp3 file didn't address my issue because I constructed the MediaPlayer fine and it played the sound the first time i launched the app.

Does anyone see an issue with this code?

1

1 Answers

1
votes

Firstly, don't call prepareAsync() on a MediaPlayer you've created using MediaPlayer.create(), as prepare() is taken care of for you.

From the docs:

http://developer.android.com/reference/android/media/MediaPlayer.html

MediaPlayer.onCreate()...

Convenience method to create a MediaPlayer for a given resource id. On success, prepare() will already have been called and must not be called again.

Since you're releasing your MediaPlayer in onPause(), if you want to play again in onResume(), you're going to have to create a new MediaPlayer using MediaPlayer.onCreate().

I suggest that you simply don't release the MediaPlayer in onPause(), call mP.pause() instead of mP.stop(), and then you don't have to worry about recreating/preparing the MediaPlayer in onResume().

Here's an example:

private MediaPlayer mMediaPlayer;
private boolean mIsPrepared;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mMediaPlayer = MediaPlayer.create(this, R.raw.raw1);
    mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mIsPrepared = true;
        }
    });
}

@Override
protected void onResume() {
    super.onResume();

    if (mMediaPlayer != null && mIsPrepared) {
        mMediaPlayer.seekTo(0);
        mMediaPlayer.start();
    }
}

@Override
protected void onPause() {
    super.onPause();

    if(mMediaPlayer!=null && mIsPrepared){
        mMediaPlayer.pause();
    }
}