18

I'm trying to add a button to my android app where it plays an MP3 when the button is tapped. I've gotten it working, but without a way to release the mediaPlayer object - therefore it keeps playing even after I leave the activity. If I initialize the MediaPlayer object outside of my react() method(what gets called when the button is pressed) it causes the app to force close when the activity is opened. But if I initialize the MediaPlayer within the react() method I then can't use mplayer.release in the onQuit() method. What am I not seeing here?

    public void react(View view) {
    MediaPlayer mediaPlayer = MediaPlayer.create(ToBeOrNot.this, R.raw.achord);
    mediaPlayer.start();
}
protected void onStop(){
    mediaPlayer.release();
    mediaPlayer = null;
}

Doesn't work for obvious reasons and

MediaPlayer mediaPlayer = MediaPlayer.create(ToBeOrNot.this, R.raw.achord);
public void react(View view) {
            mediaPlayer.start(); 
}
protected void onStop(){
    mediaPlayer.release();
    mediaPlayer = null;
}

Causes it to force close.

Update: Here is the whole java class.

public class ToBeOrNot extends Activity {

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

        }
MediaPlayer mediaPlayer;

public void react(View view) {
        mediaPlayer = MediaPlayer.create(ToBeOrNot.this, R.raw.achord);
        mediaPlayer.start(); 
}
protected void onStop(){
    mediaPlayer.release();
    mediaPlayer = null;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    //getMenuInflater().inflate(R.menu.activity_to_be_or_not, menu);
    // Locate MenuItem with ShareActionProvider
   return true;
}

}

I think what it does is relatively self explanatory. When called, it shows some text plus a button that when tapped starts a recording playing. When someone hits the back button, it should go back to the previous activity and stop the recording. Thanks for helping me!

dhsmith
  • 250
  • 1
  • 2
  • 11
  • If your other question was answered and you want to ask a new one, you should open a new question, not simply edit this one. – Geobits Feb 23 '13 at 23:01
  • Alright, I will, just didn't want to make too many questions. – dhsmith Feb 23 '13 at 23:06
  • Here's the new question. http://stackoverflow.com/questions/15046888/android-mediaplayer-causing-force-close-onquit If you feel like answering that would be great, thank you. Or someone else might, or I might come up with the answer myself. – dhsmith Feb 23 '13 at 23:21

3 Answers3

27

You can't initialize the mediaplayer object outside of all methods. If you do, it tries to use a context which hasn't been created yet. You need to declare it as a class variable(outside the method), and initialize it inside:

MediaPlayer mediaPlayer;

public void react(View view) {
    mediaPlayer = MediaPlayer.create(ToBeOrNot.this, R.raw.achord);
    mediaPlayer.start(); 
}

protected void onStop(){
    mediaPlayer.release();
    mediaPlayer = null;
}

In addition, I'd recommend reading up on variable scope in Java.

Geobits
  • 22,218
  • 6
  • 59
  • 103
  • Ah, thanks so much! That was a really dumb mistake. I realized that scope was what I was having trouble with, but my brain wasn't working and I couldn't think of how to fix it. – dhsmith Feb 23 '13 at 22:03
  • So I copied your example and now it runs fine but when I push the back button after pushing the button that starts the sound, the app force closes. Any thoughts? – dhsmith Feb 23 '13 at 22:28
  • There are a lot of potential problems with it. I'd suggest making another question, explaining what you're doing in all the lifecycle methods(create, resume, pause, stop, etc). Also, explain what exactly you *want* it to do. – Geobits Feb 23 '13 at 22:33
  • 1
    Check if mediaPlayer is null before releasing: if (mediaPlayer != null) mediaPlayer.release(); – Pablo Alfonso Apr 06 '20 at 21:38
3

According to Google docs, you can implement a listener in MediaPlayer like the below example.

You can Release and Reset automatically when it's complete.

MediaPlayer mp = MediaPlayer.create(context, R.raw.sound_one);
mp.setOnCompletionListener(new OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mp) {
        mp.reset();
        mp.release();
        mp=null;
    }
});
mp.start();
Arpit Patel
  • 7,212
  • 5
  • 56
  • 67
1

This Worked for me well.

public class MainActivity extends AppCompatActivity {

    MediaPlayer mediaPlayer;

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

        mediaPlayer = MediaPlayer.create(this, R.raw.beep_warning);

        final CheckBox checkBox = (CheckBox) findViewById(R.id.checkBox);
        checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (checkBox.isChecked()) {
                    mediaPlayer.start();
                    mediaPlayer.setLooping(true);
                }
                else{
                    mediaPlayer.pause();
                }
                }


        });

    }
    @Override
    protected void onStop() {
        super.onStop();
        mediaPlayer.release();
    }
Luiz Fernando Salvaterra
  • 4,192
  • 2
  • 24
  • 42