2012-04-04 96 views
1

我有一个播放声音的按钮。 当我多次按下按钮时,它会多次播放声音。 这是oke,我想要这个。 但是当我点击停止按钮时,它必须停止当前正在播放的所有声音。 我用:MediaPlayer如何停止播放多个声音

while (mediaPlayer.isPlaying()){mediaPlayer.stop();} 

,但它不工作,声音再玩。有人能帮我吗? 这里是我的全码:

public class HelloSoundboard extends Activity { 
MediaPlayer mediaPlayer; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    Button item1 = (Button)findViewById(R.id.item1); 
    item1.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) { 
      mediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.atyourservice); 
      mediaPlayer.start(); 
     } 
    }); 

    Button stop = (Button)findViewById(R.id.stop); 
    stop.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) { 
      while (mediaPlayer.isPlaying()){mediaPlayer.stop();} 
     // mediaPlayer.stop(); 
     } 
    }); 
} 
} 

回答

2

SoundPool是用于此目的的更好的选择。我会强烈反对实例化多个MediaPlayer实例,因为大多数系统没有资源来生成许多并行活动实例。你会发现在许多设备上按下5次以上的按钮会导致内存崩溃。

就停止所有活动流而言,这里没有烘焙功能,但很容易以类似于现有代码的方式完成。作为一个方面说明,有一个autoPause()方法,它会暂停所有流,但它不会真正结束它们的播放(如方法名称所暗示的那样)。下面是一个简单的例子来管理您的音频流:

//SoundPool initialization somewhere 
SoundPool pool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0); 
//Load your sound effect into the pool 
int soundId = pool.load(...); //There are several versions of this, pick which fits your sound 

List<Integer> streams = new ArrayList<Integer>(); 
Button item1 = (Button)findViewById(R.id.item1); 
item1.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View view) { 
     int streamId = pool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f); 
     streams.add(streamId); 
    } 
}); 

Button stop = (Button)findViewById(R.id.stop); 
stop.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View view) { 
     for (Integer stream : streams) { 
      pool.stop(stream); 
     } 
     streams.clear(); 
    } 
}); 

这是更高效的内存管理流ID值的列表比MediaPlayer情况下,你的用户会感谢你。另外请注意,即使streamID不再有效,也可以拨打SoundPool.stop(),因此您无需检查现有播放。

HTH

+0

非常好(borat语音),谢谢!!! – John 2012-04-04 15:03:38

+1

必须注意的是,SoundPool是为了小音效而制作的,缓冲区不能长到很大。我的一个声音由于其长度而被切断。所以我仍然需要使用MediaPlayer – John 2012-04-04 22:51:58

2

我不知道这一点,但我认为是更好,如果你使用的Soundpool。

“SoundPool专为短片而设计,可以保存在内存中以便快速访问,这非常适合应用程序或游戏中的音效。

“MediaPlayer专为较长的声音文件或流而设计,最适合用于音乐文件或较大的文件。

+0

谢谢,我试了一下SoundPool,但无法停止播放声音。在WWW上也找不到任何东西,你知道如何停止soundpool中的所有声音吗? – John 2012-04-04 13:00:46

+0

+1因为这是一个更好的解决方案,我只需添加自己的答案即可完全解释原因。 – Devunwired 2012-04-04 14:39:14

2

您可以使用MediaPlayer个清单:

List<MediaPlayer> mps = new ArrayList<MediaPlayer>(); 
Button item1 = (Button)findViewById(R.id.item1); 
item1.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View view) { 
     MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.raw.atyourservice); 
     mp.start(); 
     mps.add(mp); 
    } 
}); 

Button stop = (Button)findViewById(R.id.stop); 
stop.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View view) { 
     for (int i = mps.size() - 1; i >= 0; --i) { //changed ++i to --i 
      if (mps.get(i).isPlaying()) { 
       mps.get(i).stop(); 
      } 
      mps.remove(i); 
     } 
    } 
}); 
+0

我的代码如下错误: 方法add(MediaPlayer)类型列表不适用于参数(void) – John 2012-04-04 14:09:41

+0

我的错误,请参阅编辑 – MByD 2012-04-04 14:16:26