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的时候释放相应的资源

好了今天的内容就这么多了,有什么不明白的地方欢迎骚扰...

相关文章
相关标签/搜索