安卓的SoundPool(音效池)播放声音(及具体参数解析)

SoundPool一般用来播放的文件特点有:声音短,文件小,延时慢(不像使用MediaPlayer类播放音乐时,需要等待一段时间),因此常用来播放游戏时的音效,解锁时的铃声等。注意:该类不适合播放太大的文件资源,我测试了个900K左右的文件,播放不了


使用SoundPool一般需要下面几个步骤:

1、将音乐文件拷贝到工程下;

2、新建一个SoundPool实例;

3、使用load()方法,让SoundPool实例加载音效资源,该方法会返回一个整型的soundID,在第四步需要用到;

4、使用play()方法播放音效,该方法会返回一个整型的streamID,这个返回值可以保存起来,在需要暂停 /  恢复播放时需要用到。


具体实现以及参数如下:


1、新建一个工程,我取名SoundPoolDemo,在res文件夹下新建一个raw文件夹,将.mp3文件拷贝到其中


2、新建一个SoundPool实例。SoundPool只有一个构造方法,

SoundPool(int maxStreams, int streamType, int srcQuality)

参数如下:

int  maxStreams:在声音池中允许同时存在的声音数量。当池子中的声音超过这个数量时,优先级(后面会提到)最低、或者最早(Oldest,原谅我可怜的翻译水平)放进池中的,将被移除。这个数值不是越大越好,因为越大也就意味着,Android会给你预分配一个更大的空间,如果不需要使用会造成浪费。

int  streamType:声音流的类型,有STREAM_RING、STREAM_MUSIC等等,一般都是使用后者,即AudioManager.STREAM_MUSIC。

int srcQuality:官网解释为“采样速率转化器的质量”(再次原谅我的翻译),这个参数目前没有什么实际意义(可能还没实现这个功能),所以设置什么数值都无所谓,官方建议用0;


3、加载资源方法:

public int load(Context context, int resId, int priority)

参数如下:

Context  context:这个不必多解释,一般都是设置为getApplicationContext()获取

int resId:想要加载的音效资源ID,我用的是R.raw.XXX

int priority:音效播放时的优先级,官方解释这个参数在这个方法中不起作用,建议用1暂时代替(Currently has no effect. Use a value of 1 for future compatibility.

注:该方法会返回一个soundID,在以后使用中需要使用


4、播放

07-08注:在load声音资源后,并不能立即调用play,否则无法播放声音,因为声音资源还没加载完成,应该给足够时间让它加载完成,比如在onCreate中load,在onclick中play

public final int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)

参数如下:

int  soundID:在第3步中提到了。

float  leftVolume:左声道音量大小,这是一个相对值,大小在0.0f - 1.0f之间,具体计算方法为:你想要的声音大小 / 最大音量,比如取值0.8f表示最大音量的80%

float  rightVolume:右声道音量大小,具体如上

int  priority:优先级,值越大优先级越高,0的优先级最低。之前在第3步中也有一个优先级参数,但是那里无效,而现在这里的这个参数是正儿八经有效果的。

int loop:是否需要循环播放,取值不限。其中负数表示无穷循环(官方建议,如果无穷循环,用-1,当然-2、-3等也行),非负数表示循环次数,比如0表示循环0次,也就是播放一次就不再循环了,总共就只播放一次;1则表示循环1次(总共播放2次)。

float  rate:这个参数有点意思,可以理解为播放速率(就是快进、快退啥的),取值0.5f - 2.0f,其中0.5表示播放速度为正常的0.5倍。1表示正常速率播放。



下面开始正式编码:

1、资源文件如下图:

安卓的SoundPool(音效池)播放声音(及具体参数解析)_第1张图片

2、布局文件不解释了,只有一个简单的Button。下面是MainActivity.java的代码(总共就一个类)

[java] view plain copy
  1. package com.exam.soundpooldemo;  
  2.   
  3. import android.app.Activity;  
  4. import android.media.AudioManager;  
  5. import android.media.SoundPool;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.Button;  
  10.   
  11. public class MainActivity extends Activity {  
  12.   
  13.     Button playButton;  
  14.     SoundPool sp;  
  15.     int soundID_1,soundID_2;  
  16.     int streamID_1,streamID_2;  
  17.       
  18.     @Override  
  19.     protected void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21.         setContentView(R.layout.activity_main);  
  22.           
  23.         sp=new SoundPool(10, AudioManager.STREAM_MUSIC,0);  
  24.         soundID_1=sp.load(getApplicationContext(), R.raw.lingsheng, 1);  
  25.         soundID_2=sp.load(getApplicationContext(), R.raw.moon, 1);  
  26.           
  27.         playButton=(Button)findViewById(R.id.play);  
  28.         playButton.setOnClickListener(new OnClickListener() {  
  29.               
  30.             @Override  
  31.             public void onClick(View v) {  
  32.                 streamID_1=sp.play(soundID_1, 0.8f, 0.8f,1, -11.0f);  
  33.                 streamID_2=sp.play(soundID_2, 0.8f, 0.8f,1, -11.0f);  
  34.             }  
  35.         });  
  36.     }  
  37. }  

发现按下按钮,可以听到两种音效同时播放(因为我的代码中是播放2种)。


尾声:

前面提到播放音效的方法play()会返回一个streamID,这个返回值在暂停 / 恢复时需要用到,比如恢复:

[java] view plain copy
  1. public final void resume (int streamID)  
看到了吧,所以最好用一些变量将他们保存起来。


如果还有不懂的,可以直接参考API:

http://www.android-doc.com/reference/android/media/SoundPool.html

你可能感兴趣的:(Android)