Android - How do I only allow one instance of MediaPlayer to play at a time?

Goran picture Goran · Mar 20, 2011 · Viewed 9.7k times · Source

I'm trying to create a simple Sound-board Android app, using ListView items as buttons. (Btw, I'm a novice programmer)

The idea is that I press a button, and a specific sound file plays. If I press any button while a sound is playing, it should first stop that sound and then start to play the new one.

Currently the sounds play without stopping any currently playing sounds, so that if I spam the buttons I get multiple sounds playing at the same time (and if I press too many at once, the app force closes).

I have tried using a few variations of:

if (mp.isPlaying()) {
  mp.stop();
}

But according to what I read on a few other sources, I am creating multiple instances of the MediaPlayer class, and even though they have the same name the stop() method tries to stop on the latest instance of mp (in some cases it isn't even created yet).

I'm guessing my general implementation of the MediaPlayer class is wrong, but it's the best I could figure out to do.

Anyways, here's the relevant block of code:

public class soundTest extends Activity {
  private ListView lv1;
  private String lv_arr[]={"test 1","test 2","test 3","test 4","test 5"};

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    lv1=(ListView)findViewById(R.id.ListView01);
    lv1.setAdapter(new ArrayAdapter<String>(this,R.layout.list_item, lv_arr));

    lv1.setOnItemClickListener(new OnItemClickListener() {
      public void onItemClick(AdapterView<?> parent, View view,int position, long id) {

        if (lv1.getItemAtPosition(position)=="test 1") {
          MediaPlayer mp = MediaPlayer.create(getApplicationContext(),R.raw.sound1);
          mp.start();
          mp.setOnCompletionListener(new OnCompletionListener() {
            public void onCompletion(MediaPlayer mp) {
              mp.release();
            }
          });
        }

        if (lv1.getItemAtPosition(position)=="test 2") {
          MediaPlayer mp = MediaPlayer.create(getApplicationContext(),R.raw.sound2);
          mp.start();
          mp.setOnCompletionListener(new OnCompletionListener() {
            public void onCompletion(MediaPlayer mp) {
              mp.release();
            }
          });
        }

        //And the rest of the sounds 3,4,5.

      }
    });
  }
}

Any help would be appreciated, thanks.

Edit (22nd March):

I've found the following piece of code that should work:

mp.setDataSource(context, Uri.parse("android.resource://" + Config.PACKAGE + "/" + resId));

But, I can't figure out how the "Config.PACKAGE" part works. I just get an error "PACKAGE cannot be resolved, or is not a field".

I tried replacing "PACKAGE" with the package name, same error. I also tried:

try {
  mp.setDataSource(getApplicationContext(),Uri.parse("android.resource://com.mptest/" + R.raw.test2));
} catch (IOException e) {
  e.printStackTrace();
}

But I can't work what exactly to put in place of "//com.mptest/".

Answer

mar picture mar · Dec 5, 2012

The global variable MediaPlayer needs to be set private static. This has caught me several times.