MediaPalyer虽然可以播放音频,但是资源占用量较高、延迟时间较长、不支持多个音频同时播放等缺点,SoundPool一般用来播放密集、急促、短暂的音效
导入音频文件
Android工程的音频文件存放在raw文件夹
页面布局
没啥好看的
1 2 3 4 5 6 7 8 9 10 11 12
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:gravity="center" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:text="播放音频" android:id="@+id/sound_btn1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
|
程序设计
Android5.0是SoundPool的一个分水岭,在5.0版本SoundPool发生了大变化
1 2 3 4 5 6 7
| if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLIPOP){ } else { }
|
SDK_INT >= 21
1.创建SoundPool的构建对象
1 2 3 4
| SoundPool.Builder builder = new SoundPool.Builder();
builder.setMaxStreams(1);
|
2.创建AudioAttributes的构建对象,它封装音频各种属性的方法,使用它设置音频流的合适的属性并加载到SoundPool的构建对象
1 2 3 4 5 6
| AudioAttributes.Builder audioAttriBuilder = new AudioAttributes.Builder();
audioAttriBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
builder.setAudioAttributes(audioAttriBuilder.build());
|
3.通过build()方法得到SoundPool对象
1 2
| soundPool = builder.build();
|
SDK_INT < 21
1 2
| soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC,0);
|
加载播放
1.加载音频资源,load会返回一个int类型的id,该id用于控制这个音效,开始、卸载等
1 2
| soundId = soundPool.load(MySoundPool.this,R.raw.lbw,3);
|
2.音频资源加载完成后,播放音频
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() { @Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { if (status == 0){
soundPool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f); } } });
|
卸载并释放
由于一个SoundPool对象可能播放很多个音效,所以在页面销毁时再对它进行释放
1 2 3 4 5 6 7
| protected void onDestroy() { super.onDestroy();
soundPool.unload(soundId);
soundPool.release(); }
|
完整程序预览
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| import androidx.appcompat.app.AppCompatActivity;
import android.media.AudioAttributes; import android.media.AudioManager; import android.media.SoundPool; import android.os.Build; import android.os.Bundle; import android.view.View; import android.widget.Button;
public class MySoundPool extends AppCompatActivity { private Button sound_btn1; private SoundPool soundPool; private int soundId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sound_pool);
sound_btn1 = findViewById(R.id.sound_btn1); sound_btn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
SoundPool.Builder builder = new SoundPool.Builder();
builder.setMaxStreams(1);
AudioAttributes.Builder audioAttriBuilder = new AudioAttributes.Builder();
audioAttriBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
builder.setAudioAttributes(audioAttriBuilder.build());
soundPool = builder.build(); } else {
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC,0); }
soundId = soundPool.load(MySoundPool.this,R.raw.lbw,3);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() { @Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { if (status == 0){
soundPool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f); } } }); } }); } @Override protected void onDestroy() { super.onDestroy();
soundPool.unload(soundId);
soundPool.release(); } }
|
扩展
SoundPool一般用来播放密集、急促、短暂的音效,所以它对一个音频文件最大只播放6秒
若要突破这个限制
- 将声音文件的采样率更改为16000Hz。
- 将音频通道改为单声道,而不是立体声。
- 将声音文件转换为ogg格式。
- 确保经过这些过程后文件小于1mb。