Android中實現短音頻和震動的一些總結

好長時間沒有寫博客了,由於最近事情比較多。因此好長時間沒有寫博客了。堅持是一件很辛苦的事情。但還須要努力。。。好了,閒話不扯了。由於最近項目中用到了相應的短音頻和震動的功能,因此這裏總結一下相應的內容!java

本文知識點:

    1. 音頻中的一些知識和經常使用的API介紹;
    1. 震動中的一些知識和經常使用的API介紹;
    1. 簡單的使用和封裝;

1. 音頻中的一些知識介紹和經常使用的API

1.1 關於短音頻一些知識的介紹

在項目中忽然有個需求,就是實現短音頻,比如短信音那種!最開始想到的方案就是MediaPlayer解決。可是我隨手百度了一下,發現其實Android提供了一個單獨播放短音頻的 類(SoundPool),爲何是它呢?由於soundPool用於播放密集,急促的短暫音效,例如微信的搖一搖等。。。SoundPool使用了音效池的來播放音頻,若是超過流的最大數目,SoundPool會基於優先級自動中止先前播放的流。因此播放短促且密集的音頻應該使用SoundPool進行相應的播放,好了就簡單介紹到這裏吧!android

1.2 音頻的一些相應的API介紹

這裏說明一點,在android5.0的時候廢棄了相應SoundPool使用構造方法的建立,因此爲了兼容,在建立的時候要進行相應的適配!相應的適配代碼以下:數組

1.2.1 構造對象的方法

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簡介

其實就是幾個重載的方法,基本上就是傳入參數進行相應的加載資源。微信

  1. load(Context context, int resId, int priority)
  2. load(String path, int priority)
  3. load(FileDescriptor fd, long offset, long length, int priority)
  4. load(AssetFileDescriptor afd, int priority)

上述方法都會返回一個聲音的ID(這個ID對應後面的soundID),後面咱們能夠經過這個ID來播放指定的聲音。ide

由於使用的參數都差很少,因此這裏統一進行講解一下:函數

  • context 上下文,沒有什麼好說的
  • resId 資源Id(這裏說明一下:通常音頻文件都會放在res->raw文件夾下)
  • priority 沒有什麼實際用處,這裏傳入1就行了
  • path 文件路徑
  • AssetFileDescriptor:從asset目錄讀取某個資源文件,用法: AssetFileDescriptor descriptor = assetManager.openFd("biaobiao.mp3");
  1. play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)

上面是開始播放的代碼,參數含義以下:工具

  • soundID load()返回的相應索引
  • leftVolume:左聲道音量設置
  • rightVolume:右聲道音量設置
  • priority:指定播放聲音的優先級,數值越高,優先級越大。
  • loop:指定是否循環:-1表示無限循環,0表示不循環,其餘值表示要重複播放的次數
  • rate:指定播放速率:1.0的播放率可使聲音按照其原始頻率,而2.0的播放速率,可使聲音按照其 原始頻率的兩倍播放。若是爲0.5的播放率,則播放速率是原始頻率的一半。播放速率的取值範圍是0.5至2.0
  1. release() 釋放相應的資源
  2. setOnLoadCompleteListener(OnLoadCompleteListener listener) 文件加載完畢的監聽

以上就是SoundPool的一些常見API,基本上上面的代碼就能夠輕鬆的使用SoundPool了!oop

2. 震動中的一些知識和經常使用的API介紹

2.1 震動的一些知識點介紹

關於震動沒有什麼好說的,只能使用Vibrator進行開發,可是切記一點就是權限的聲明,基本上只要相關的權限處理好了,震動仍是很容易的。哦,忘記了,這個也要進行相應的版本適配,下面會說到的。ui

2.2 一些相應的API介紹

2.2.1 構造函數的建立

Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
複製代碼

這個沒有什麼好說的,就是系統的相應服務。spa

2.2.2 常見的API簡介

幾個相應的重載方法

  1. vibrate(long milliseconds);
  2. vibrate(long milliseconds, AudioAttributes attributes);
  3. vibrate(long[] pattern, int repeat);
  4. vibrate(long[] pattern, int repeat, AudioAttributes attributes);

其實調用這個就能夠直接進行相應的震動了,因此說挺簡單的。解釋一下相應的參數含義

  • milliseconds 震動的持續時間
  • attributes 震動的屬性,AudioAttributes類中定義了不少的屬性,感興趣的能夠嘗試一下
  • pattern 這是一個數組,能夠實現一個間斷的震動效果(第一個值表示在打開振動器以前要等待的毫秒數下一個值表示在關閉振動器以前保持振動器的毫秒數)實驗一下就能夠了。
  • repeat 振動重複的模式 。"-1"表明不重複

記得我上面說過關於版本適配的問題吧,其實在26版本也就是Android O的時候,須要進行相應的適配,使用了VibrationEffect封裝了一層。

  1. vibrator.vibrate(long milliseconds); 設置手機震動
  2. vibrator.hasVibrator(); 判斷手機硬件是否有振動器
  3. vibrator.cancel(); 關閉振動
  4. VibrationEffect vibrationEffect = VibrationEffect.createOneShot(long milliseconds, int amplitude);
  5. VibrationEffect vibrationEffect = VibrationEffect.createWaveform(long[] timings, int repeat);
  6. VibrationEffect vibrationEffect = VibrationEffect.createWaveform(long[] timings, int[] amplitudes, int repeat);

也就是說以前直接調用的代碼經過VibrationEffect進行了相應的封裝。解釋一個參數

  • amplitude 振幅值. 振幅在0~255之間,隨便選擇一個吧
  1. vibrate(VibrationEffect vibe); 開啓震動
  2. vibrate(VibrationEffect vibe, AudioAttributes attributes); 開啓震動

3. 簡單的使用和封裝

基本上關於短音頻和振幅的內容就是上面這些,基本上按照上面這些進行相應的組合就能夠了.可是爲了你們的方便,我簡單的封裝了一個工具類給你們使用.封裝的很差還請見諒!!!

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;

    /** * 音頻的相關類 */
    private SoundPool mSoundPool;
    private Context mContext;
    private Vibrator mVibrator;


    private SoundPoolUtils(Context context) {
        mContext = context;
        //初始化行營的音頻類
        intSoundPool();
        initVibrator();
    }

    /** * @author Angle * 建立時間: 2018/11/4 13:02 * 方法描述: 初始化短音頻的內容 */
    private void intSoundPool() {
        //根據不一樣的版本進行相應的建立
        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 * 建立時間: 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 * 建立時間: 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 * 建立時間: 2018/11/4 13:04 * 方法描述: 開啓相應的震動 */
    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 * 建立時間: 2018/11/4 13:06 * 方法描述: 同時開始音樂和震動 */
    public void startVideoAndVibrator(int resId, long milliseconds) {
        playVideo(resId);
        startVibrator(milliseconds);
    }

    /** * @author Angle * 建立時間: 2018/11/4 13:05 * 方法描述: 釋放相應的資源 */
    public void release() {
        //釋放全部的資源
        if (mSoundPool != null) {
            mSoundPool.release();
            mSoundPool = null;
        }

        if (mVibrator != null) {
            mVibrator.cancel();
            mVibrator = null;
        }
    }
}
複製代碼

由於咱們項目中,只用到了相應的播放一個短音頻因此這裏就只簡單的封裝了一下.見諒!!!

使用起來就很簡單了,在你使用的地方直接調用

  • startVibrator 單獨的震動
  • playVideo 單獨的聲音
  • startVideoAndVibrator 震動加聲音
  • release 在onPause的時候釋放相應的資源

好了今天的內容就這麼多了,有什麼不明白的地方歡迎騷擾...

相關文章
相關標籤/搜索