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

早过忘川 提交于 2020-12-05 12:20:48

问题


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/".


回答1:


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




回答2:


Don't use a global. Use the singleton pattern. That is what it is for, so that you can have exactly one instance w/o using a global variable.

There are lots of good examples of Java code for this pattern, start with http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html and you can't go wrong.




回答3:


Consider keeping your MediaPlayer as a global variable instead of having multiple instances of it.




回答4:


You might find a good reference in the VideoView Source, since it handles one MediaPlayer object and you may change content during playback.



来源:https://stackoverflow.com/questions/5367982/android-how-do-i-only-allow-one-instance-of-mediaplayer-to-play-at-a-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!