SoundPool一般用來 播放密集,急促而又短暫的音效,比如特技音效:Duang~,游戲用得較多,你也可以為你的 APP添加上這個音效,比如酷狗音樂進去的時候播放"哈嘍,酷狗",其實這個創(chuàng)意還是不錯的 間接的讓用戶知道了當(dāng)前播放器的音量,不然用戶一放歌,突然來了一發(fā)小蘋果,引得附近 大媽起舞就不好了是吧;除了可以在音樂播放器加,你還可以在普通APP加上,比如收到推送 信息或者新的聊天信息,然后播放提示音,比如超級課程表新版本,加了這玩意,收到推送 信息會播放一段短促的"表表"的聲音!SoundPool對象可以看作是一個可以從APK中導(dǎo)入資源 或者從文件系統(tǒng)中載入文件的樣本集合。它利用MediaPlayer服務(wù)為音頻解碼為一個原始16位 PCM流。這個特性使得應(yīng)用程序可以進行流壓縮,而無須忍受在播放音頻時解壓所帶來的CPU 負載和延時。SoundPool使用音效池的概念來管理多個播放流,如果超過流的最大數(shù)目, SoundPool會基于優(yōu)先級自動停止先前播放的流,另外,SoundPool還支持自行設(shè)置聲音的品質(zhì)、 音量、 播放比率等參數(shù),代碼如下:

image.png
package com.example.soundpooldemo;
import androidx.appcompat.app.AppCompatActivity;
import android.content.res.AssetManager;
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.Toast;
import java.io.IOException;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private final HashMap<Integer, Integer> soundIds = new HashMap<>();
private AssetManager assetManager;
private SoundPool soundPool;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.bt_main_play1).setOnClickListener(this);
findViewById(R.id.bt_main_play2).setOnClickListener(this);
findViewById(R.id.bt_main_play3).setOnClickListener(this);
findViewById(R.id.bt_main_play4).setOnClickListener(this);
findViewById(R.id.bt_main_play5).setOnClickListener(this);
findViewById(R.id.bt_main_release).setOnClickListener(this);
assetManager = getAssets();
initSoundPool();
}
private void initSoundPool() {
if (Build.VERSION.SDK_INT >= 21) {
//argetSDK版本要設(shè)置大于等于21哦!而且如果minSDK版本小于21 否則會報錯
SoundPool.Builder soundPoolBuilder = new SoundPool.Builder();
soundPoolBuilder.setMaxStreams(5);
AudioAttributes.Builder audioAttributesBuilder = new AudioAttributes.Builder();
audioAttributesBuilder.setLegacyStreamType(AudioManager.STREAM_SYSTEM);//同下
soundPoolBuilder.setAudioAttributes(audioAttributesBuilder.build());
soundPool = soundPoolBuilder.build();
} else {
/**
* maxStreams 指定支持多少個聲音,SoundPool對象中允許同時存在的最大流的數(shù)量
* streamType 指定聲音類型,流類型可以分為STREAM_VOICE_CALL, STREAM_SYSTEM, STREAM_RING,STREAM_MUSIC 和 STREAM_ALARM四種類型。在AudioManager中定義。
* srcQuality 指定聲音品質(zhì)(采樣率變換質(zhì)量),一般直接設(shè)置為0!
*/
soundPool = new SoundPool(5, AudioManager.STREAM_SYSTEM, 5);
}
// priority 指定播放聲音的優(yōu)先級,數(shù)值越高,優(yōu)先級越大。
soundIds.put(1, soundPool.load(this, R.raw.duang, 1));
try {
soundIds.put(2, soundPool.load(assetManager.openFd("biaobiao.mp3"), 1));
} catch (IOException e) {
e.printStackTrace();
}
soundIds.put(3, soundPool.load(this, R.raw.duang, 1));
soundIds.put(4, soundPool.load(this, R.raw.duang, 1));
soundIds.put(5, soundPool.load(this, R.raw.duang, 1));
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
Toast.makeText(MainActivity.this, "音頻已準備好了!", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_main_play1:
/*
soundID:Load()返回的聲音ID號
leftVolume:左聲道音量設(shè)置
rightVolume:右聲道音量設(shè)置
priority:指定播放聲音的優(yōu)先級,數(shù)值越高,優(yōu)先級越大。
loop:指定是否循環(huán):-1表示無限循環(huán),0表示不循環(huán),其他值表示要重復(fù)播放的次數(shù)
rate:指定播放速率:1.0的播放率可以使聲音按照其原始頻率,而2.0的播放速率,可以使聲音按照其 原始頻率的兩倍播放。
如果為0.5的播放率,則播放速率是原始頻率的一半。播放速率的取值范圍是0.5至2.0。
*/
soundPool.play(soundIds.get(1), 1, 1, 0, 0, 0);
break;
case R.id.bt_main_play2:
soundPool.play(soundIds.get(2), 1, 1, 0, 0, 0);
break;
case R.id.bt_main_play3:
soundPool.play(soundIds.get(3), 1, 1, 0, 0, 0);
break;
case R.id.bt_main_play4:
soundPool.play(soundIds.get(4), 1, 1, 0, 0, 0);
break;
case R.id.bt_main_play5:
soundPool.play(soundIds.get(5), 1, 1, 0, 0, 0);
break;
case R.id.bt_main_release:
//可以調(diào)用release()方法釋放所有SoundPool對象占據(jù)的內(nèi)存和資源,當(dāng)然也可以根據(jù)聲音 ID來釋放!
soundPool.release();
break;
}
}
}

image.png