好長時間沒有寫博客了,因為最近事情比較多。所以好長時間沒有寫博客了。堅持是一件很辛苦的事情。但還需要努力。。。好了,閑話不扯了。因為最近項目中用到了相應(yīng)的短音頻和震動的功能,所以這里總結(jié)一下相應(yīng)的內(nèi)容!
本文知識點:
- 音頻中的一些知識和常用的API介紹;
- 震動中的一些知識和常用的API介紹;
- 簡單的使用和封裝;
1. 音頻中的一些知識介紹和常用的API
1.1 關(guān)于短音頻一些知識的介紹
在項目中突然有個需求,就是實現(xiàn)短音頻,好比短信音那種!最開始想到的方案就是MediaPlayer解決。但是我隨手百度了一下,發(fā)現(xiàn)其實Android提供了一個單獨播放短音頻的 類(SoundPool),為什么是它呢?因為soundPool用于播放密集,急促的短暫音效,例如微信的搖一搖等。。。SoundPool使用了音效池的來播放音頻,如果超過流的最大數(shù)目,SoundPool會基于優(yōu)先級自動停止先前播放的流。所以播放短促且密集的音頻應(yīng)該使用SoundPool進行相應(yīng)的播放,好了就簡單介紹到這里吧!
1.2 音頻的一些相應(yīng)的API介紹
這里說明一點,在android5.0的時候廢棄了相應(yīng)SoundPool使用構(gòu)造方法的創(chuàng)建,所以為了兼容,在創(chuàng)建的時候要進行相應(yīng)的適配!相應(yīng)的適配代碼如下:
1.2.1 構(gòu)造對象的方法
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mSoundPool = new SoundPool.Builder()
.setMaxStreams(MAX_STREAMS)
.build();
} else {
mSoundPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, DEFAULT_QUALITY);
}
1.2.2 常見的API簡介
其實就是幾個重載的方法,基本上就是傳入?yún)?shù)進行相應(yīng)的加載資源。
- load(Context context, int resId, int priority)
- load(String path, int priority)
- load(FileDescriptor fd, long offset, long length, int priority)
- load(AssetFileDescriptor afd, int priority)
上述方法都會返回一個聲音的ID(這個ID對應(yīng)后面的soundID),后面我們可以通過這個ID來播放指定的聲音。
因為使用的參數(shù)都差不多,所以這里統(tǒng)一進行講解一下:
- context 上下文,沒有什么好說的
- resId 資源Id(這里說明一下:一般音頻文件都會放在res->raw文件夾下)
- priority 沒有什么實際用處,這里傳入1就好了
- path 文件路徑
- AssetFileDescriptor:從asset目錄讀取某個資源文件,用法: AssetFileDescriptor descriptor = assetManager.openFd("biaobiao.mp3");
- play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
上面是開始播放的代碼,參數(shù)含義如下:
- soundID load()返回的相應(yīng)索引
- 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
- release() 釋放相應(yīng)的資源
- setOnLoadCompleteListener(OnLoadCompleteListener listener) 文件加載完畢的監(jiān)聽
以上就是SoundPool的一些常見API,基本上上面的代碼就可以輕松的使用SoundPool了!
2. 震動中的一些知識和常用的API介紹
2.1 震動的一些知識點介紹
關(guān)于震動沒有什么好說的,只能使用Vibrator進行開發(fā),但是切記一點就是權(quán)限的聲明,基本上只要相關(guān)的權(quán)限處理好了,震動還是很容易的。哦,忘記了,這個也要進行相應(yīng)的版本適配,下面會說到的。
2.2 一些相應(yīng)的API介紹
2.2.1 構(gòu)造函數(shù)的創(chuàng)建
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
這個沒有什么好說的,就是系統(tǒng)的相應(yīng)服務(wù)。
2.2.2 常見的API簡介
幾個相應(yīng)的重載方法
vibrate(long milliseconds);
vibrate(long milliseconds, AudioAttributes attributes);
vibrate(long[] pattern, int repeat);
vibrate(long[] pattern, int repeat, AudioAttributes attributes);
其實調(diào)用這個就可以直接進行相應(yīng)的震動了,所以說挺簡單的。解釋一下相應(yīng)的參數(shù)含義
- milliseconds 震動的持續(xù)時間
- attributes 震動的屬性,AudioAttributes類中定義了很多的屬性,感興趣的可以嘗試一下
- pattern 這是一個數(shù)組,可以實現(xiàn)一個間斷的震動效果(第一個值表示在打開振動器之前要等待的毫秒數(shù)下一個值表示在關(guān)閉振動器之前保持振動器的毫秒數(shù))實驗一下就可以了。
- repeat 振動重復(fù)的模式 。"-1"代表不重復(fù)
記得我上面說過關(guān)于版本適配的問題吧,其實在26版本也就是Android O的時候,需要進行相應(yīng)的適配,使用了VibrationEffect封裝了一層。
vibrator.vibrate(long milliseconds); 設(shè)置手機震動
vibrator.hasVibrator(); 判斷手機硬件是否有振動器
vibrator.cancel(); 關(guān)閉振動
VibrationEffect vibrationEffect = VibrationEffect.createOneShot(long milliseconds, int amplitude);
VibrationEffect vibrationEffect = VibrationEffect.createWaveform(long[] timings, int repeat);
VibrationEffect vibrationEffect = VibrationEffect.createWaveform(long[] timings, int[] amplitudes, int repeat);
也就是說之前直接調(diào)用的代碼通過VibrationEffect進行了相應(yīng)的封裝。解釋一個參數(shù)
- amplitude 振幅值. 振幅在0~255之間,隨便選擇一個吧
vibrate(VibrationEffect vibe); 開啟震動
vibrate(VibrationEffect vibe, AudioAttributes attributes); 開啟震動
3. 簡單的使用和封裝
基本上關(guān)于短音頻和振幅的內(nèi)容就是上面這些,基本上按照上面這些進行相應(yīng)的組合就可以了.但是為了大家的方便,我簡單的封裝了一個工具類給大家使用.封裝的不好還請見諒!!!
public class SoundPoolUtils {
private static final int MAX_STREAMS = 2;
private static final int DEFAULT_QUALITY = 0;
private static final int DEFAULT_PRIORITY = 1;
private static final int LEFT_VOLUME = 1;
private static final int RIGHT_VOLUME = 1;
private static final int LOOP = 0;
private static final float RATE = 1.0f;
private static SoundPoolUtils sSoundPoolUtils;
/**
* 音頻的相關(guān)類
*/
private SoundPool mSoundPool;
private Context mContext;
private Vibrator mVibrator;
private SoundPoolUtils(Context context) {
mContext = context;
//初始化行營的音頻類
intSoundPool();
initVibrator();
}
/**
* @author Angle
* 創(chuàng)建時間: 2018/11/4 13:02
* 方法描述: 初始化短音頻的內(nèi)容
*/
private void intSoundPool() {
//根據(jù)不同的版本進行相應(yīng)的創(chuàng)建
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mSoundPool = new SoundPool.Builder()
.setMaxStreams(MAX_STREAMS)
.build();
} else {
mSoundPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, DEFAULT_QUALITY);
}
}
/**
* @author Angle
* 創(chuàng)建時間: 2018/11/4 13:03
* 方法描述: 初始化震動的對象
*/
private void initVibrator() {
mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
}
public static SoundPoolUtils getInstance(Context context) {
if (sSoundPoolUtils == null) {
synchronized (SoundPoolUtils.class) {
if (sSoundPoolUtils == null) {
sSoundPoolUtils = new SoundPoolUtils(context);
}
}
}
return sSoundPoolUtils;
}
/**
* @param resId 音頻的資源ID
* @author Angle
* 創(chuàng)建時間: 2018/11/4 13:03
* 方法描述: 開始播放音頻
*/
public void playVideo(int resId) {
if (mSoundPool == null) {
intSoundPool();
}
int load = mSoundPool.load(mContext, resId, DEFAULT_PRIORITY);
mSoundPool.play(load, LEFT_VOLUME, RIGHT_VOLUME, DEFAULT_PRIORITY, LOOP, RATE);
}
/**
* @param milliseconds 震動時間
* @author Angle
* 創(chuàng)建時間: 2018/11/4 13:04
* 方法描述: 開啟相應(yīng)的震動
*/
public void startVibrator(long milliseconds) {
if (mVibrator == null) {
initVibrator();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
VibrationEffect vibrationEffect = VibrationEffect.createOneShot(milliseconds, 100);
mVibrator.vibrate(vibrationEffect);
} else {
mVibrator.vibrate(1000);
}
}
/**
* @param resId 資源id
* @param milliseconds 震動時間
* @author Angle
* 創(chuàng)建時間: 2018/11/4 13:06
* 方法描述: 同時開始音樂和震動
*/
public void startVideoAndVibrator(int resId, long milliseconds) {
playVideo(resId);
startVibrator(milliseconds);
}
/**
* @author Angle
* 創(chuàng)建時間: 2018/11/4 13:05
* 方法描述: 釋放相應(yīng)的資源
*/
public void release() {
//釋放所有的資源
if (mSoundPool != null) {
mSoundPool.release();
mSoundPool = null;
}
if (mVibrator != null) {
mVibrator.cancel();
mVibrator = null;
}
}
}
因為我們項目中,只用到了相應(yīng)的播放一個短音頻所以這里就只簡單的封裝了一下.見諒!!!
使用起來就很簡單了,在你使用的地方直接調(diào)用
- startVibrator 單獨的震動
- playVideo 單獨的聲音
- startVideoAndVibrator 震動加聲音
- release 在onPause的時候釋放相應(yīng)的資源
好了今天的內(nèi)容就這么多了,有什么不明白的地方歡迎騷擾...