package wyf.ytl;
import java.util.HashMap;//引入HashMap类
import android.app.Activity;//引入Activity类
import android.content.Context;//引入Context类
import android.media.AudioManager;//引入AudioManager类
import android.media.MediaPlayer;//引入MediaPlayer类
import android.media.SoundPool;//引入SoundPool类
import android.os.Bundle;//引入Bundle类
import android.view.View;//引入View类
import android.view.View.OnClickListener;//引入OnClickListener类
import android.widget.Button;//引入Button类
import android.widget.TextView;//引入TextView类
public class Sample_2_10 extends Activity implements OnClickListener{
Button button1; //四个按钮的引用
Button button2;
Button button3;
Button button4;
TextView textView; //TextView的引用
MediaPlayer mMediaPlayer;
SoundPool soundPool; //声音
HashMap<Integer, Integer> soundPoolMap;
public void onCreate(Bundle savedInstanceState) {//重写onCreate回调方法
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initSounds(); //初始化声音
//设置显示的用户界面
textView = (TextView) this.findViewById(R.id.textView); //得到TextView的引用
button1 = (Button) this.findViewById(R.id.button1); //得到button的引用
button2 = (Button) this.findViewById(R.id.button2);
button3 = (Button) this.findViewById(R.id.button3);
button4 = (Button) this.findViewById(R.id.button4);
button1.setOnClickListener(this); //为四个按钮添加监听
button2.setOnClickListener(this);
button3.setOnClickListener(this);
button4.setOnClickListener(this);
}
public void initSounds(){ //初始化声音的方法
mMediaPlayer = MediaPlayer.create(this, R.raw.backsound); //初始化MediaPlayer
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
soundPoolMap = new HashMap<Integer, Integer>();
soundPoolMap.put(1, soundPool.load(this, R.raw.dingdong, 1));
}
public void playSound(int sound, int loop) { / /用SoundPoll播放声音的方法
AudioManager mgr = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
float streamVolumeCurrent = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
float streamVolumeMax = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = streamVolumeCurrent/streamVolumeMax;
soundPool.play(soundPoolMap.get(sound), volume, volume, 1, loop, 1f);//播放声音
}
public void onClick(View v) {//实现接口中的方法
if(v == button1){ //点击了使用MediaPlayer播放声音按钮
textView.setText("使用MediaPlayer播放声音");
if(!mMediaPlayer.isPlaying()){
mMediaPlayer.start();//播放声音
}
}
else if(v == button2){//点击了暂停MediaPlayer声音按钮
textView.setText("暂停了MediaPlayer播放的声音");
if(mMediaPlayer.isPlaying()){
mMediaPlayer.pause();//暂停声音
}
}
else if(v == button3){//点击了使用SoundPool播放声音按钮
textView.setText("使用SoundPool播放声音");
this.playSound(1, 0);
}
else if(v == button4){//点击了暂停SoundPool声音按钮
textView.setText("暂停了SoundPool播放的声音");
soundPool.pause(1);//暂停SoundPool的声音
}
}
}
而mediaplayer适合播放长点的。 SoundPool载入音乐文件使用了独立的线程,不会阻塞UI主线程的操作。但是这里如果音效文件过大没有载入完成,我
们调用play方法时可能产生严重的后果, 这里Android SDK提供了一个SoundPool.OnLoadCompleteListener类来帮助 我们了解媒体文件是否载入完成,
我们 重载 onLoadComplete(SoundPool soundPool, int sampleId, int status) 方法即可获得。从上面的onLoadComplete方法可以看出该类有很多参数,
比如类似id,是的SoundPool在load时可以处理多个媒体一次初始化并放入内存中,这里效率 比MediaPlayer高了很多。SoundPool类支持同时播放多个
音效,这对于游戏来说是十分必要的, 而MediaPlayer类是同步执行的只能一个文件一个文件的播放。
使用方法:
创建一个SoundPool
1.public SoundPool(int maxStream, int streamType, int srcQuality)
maxStream —— 同时播放的流的最大数量
streamType —— 流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出)
srcQuality —— 采样率转化质量,当前无效果,使用0作为默认值eg.
SoundPool soundPool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0); 最多支持3个流同时播放的,类型标记为音乐的SoundPool。
一般把多个声音放到HashMap中去,比如
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
HashMap soundPoolMap = new HashMap();
soundPoolMap.put(1, soundPool.load(this, R.raw.dingdong, 1));
soundpool的加载:
int load(Context context, int resId, int priority) //从APK资源载入
int load(FileDescriptor fd, long offset, long length, int priority) //从FileDescriptor对象载入
int load(AssetFileDescriptor afd, int priority) //从Asset对象载入
int load(String path, int priority) //从完整文件路径名载入,最后一个参数为优先级。
播放
play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) 其中leftVolume和rightVolume表示左右音量,priority表示优先级,loop表示循环次数,rate表示速率(速率最低0.5,最高为2,正常速度为1)。例如:play(soundId, 1, 1, 0, 0, 1);
停止
pause(int streamID) 方法,这里的streamID和soundID均在构造SoundPool类的第一个参数中指明了总数量,而id从0开始。
遗憾的是SoundPool目前存在的问题还比较多,我们需要谨慎使用,尽量避免程序在调用SoundPool过程中出现异常关闭的情况。但是如果你现在就需要使用SoundPool开发你的程序,也许你需要知道这些问题:
1. SoundPool最大只能申请1M的内存空间,这就意味着我们只能使用一些很短的声音片段,而不是用它来播放歌曲或者游戏背景音乐(背景音乐可以考虑使用JetPlayer来播放)。
2. SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。还有些朋友反映它们不会立即中止播放声音,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。
3. 音频格式建议使用OGG格式。在使用WAV格式的音频文件存放游戏音效。经过反复测试,在音效播放间隔较短的情况下会出现异常关闭的情况(有说法是SoundPool目前只对16bit的WAV文件有较好的支持)。后来将文件转成OGG格式,问题得到了解决。