#Android 实现蓝牙录音

本文实现使用AudioRecord 来进行蓝牙录音。
主要是通过打开蓝牙SCO通路实现。
这里不考虑连接蓝牙问题,要确保蓝牙连接成功。

app的界面

实现功能:普通录音、停止、播放和蓝牙录音、停止、播放。

具体的实现过程:
这里封装了打开SCO的工具类。
先是打开SCO通道后进行蓝牙录音。
使用AudioRecord 来进行蓝牙录音。
使用AudioTrack 来进行播放。

下面是打开SCO的工具类:

package com.recorder.huawei.recorderdemo;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.media.AudioManager;import android.support.annotation.NonNull;import android.util.Log;public class BluetoothUtil {    private String TAG = "BluetoothUtil";    private static BluetoothUtil mBluetoothUtil;    //第一次打开sco没成功的情况,持续连接的次数    private static final int SCO_CONNECT_TIME = 5;    private int mConnectIndex = 0;    private AudioManager mAudioManager = null;    static Context mContext;    private BluetoothUtil() {        if (mAudioManager == null) {            mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);        }    }    public static BluetoothUtil getInstance(Context context) {        mContext = context;        if (mBluetoothUtil == null) {            mBluetoothUtil = new BluetoothUtil();        }        return mBluetoothUtil;    }    public void openSco(@NonNull final IBluetoothConnectListener listener) {        if (!mAudioManager.isBluetoothScoAvailableOffCall()) {            Log.e(TAG, "系统不支持蓝牙录音");            listener.onError("Your device no support bluetooth record!");            return;        }        new Thread(new Runnable() {            @Override            public void run() {                //mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);                //蓝牙录音的关键,启动SCO连接,耳机话筒才起作用                mAudioManager.stopBluetoothSco();                mAudioManager.startBluetoothSco();                //蓝牙SCO连接建立需要时间,连接建立后会发出ACTION_SCO_AUDIO_STATE_CHANGED消息,通过接收该消息而进入后续逻辑。                //也有可能此时SCO已经建立,则不会收到上述消息,可以startBluetoothSco()前先                //stopBluetoothSco()                mConnectIndex = 0;                mContext.registerReceiver(new BroadcastReceiver() {                    @Override                    public void onReceive(Context context, Intent intent) {                        int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);                        boolean bluetoothScoOn = mAudioManager.isBluetoothScoOn();                        Log.i(TAG, "onReceive state=" + state + ",bluetoothScoOn=" + bluetoothScoOn);                        if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state) { // 判断值是否是:1                            Log.e(TAG, "onReceive success!");                            mAudioManager.setBluetoothScoOn(true);  //打开SCO                            listener.onSuccess();                            mContext.unregisterReceiver(this);  //取消广播,别遗漏                        } else {//等待一秒后再尝试启动SCO                            Log.e(TAG, "onReceive failed index=" + mConnectIndex);                            try {                                Thread.sleep(500);                            } catch (InterruptedException e) {                                e.printStackTrace();                            }                            if (mConnectIndex < SCO_CONNECT_TIME) {                                mAudioManager.startBluetoothSco();//再次尝试连接                            } else {                                listener.onError("open sco failed!");                                mContext.unregisterReceiver(this);  //取消广播,别遗漏                            }                            mConnectIndex++;                        }                    }                }, new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED));            }        }).start();    }    public void closeSco() {        boolean bluetoothScoOn = mAudioManager.isBluetoothScoOn();        Log.i(TAG, "bluetoothScoOn=" + bluetoothScoOn);        if (bluetoothScoOn) {            mAudioManager.setBluetoothScoOn(false);            mAudioManager.stopBluetoothSco();        }        mBluetoothConnectListener = null;    }    public interface IBluetoothConnectListener {        void onError(String error);        void onSuccess();    }    IBluetoothConnectListener mBluetoothConnectListener;}

之前上网查了几个资料,好几个都不好使,
有的是直接设置几个参数,那样是肯定不行的。

后面发现通过打开sco通道的方式可以进行蓝牙录音!
进行蓝牙录音要确保权限通过,蓝牙是动态权限,
还有一个是打开sco的重要权限,一定要在AndroidManafest中声明。
下面是蓝牙录音存储相关的权限:

                        

后面在评论区会附带源码和apk文件。

#共勉:你一直在等,所以你一事无成。

更多相关文章

  1. Android之存储目录
  2. Android(安卓)热敏打印机开发(蓝牙)
  3. Android复习笔记(7) -发送广播
  4. 主线程(UI线程)
  5. android--理解和使用自定义权限
  6. Mac系统配置Android(安卓)Studio的gradle命令
  7. android中push机制实现:搭建XMPP协议,实现自主推送消息到手机
  8. Android中MQTT协议的使用
  9. Android文件访问权限

随机推荐

  1. 4412开发板Android和LinuxQT烧写方法
  2. Android在线热更新hot fix - AndFix试用
  3. 如何让你的手机屏幕固定横屏和竖屏
  4. Android(安卓)开发环境的搭建 个人笔记
  5. Android(安卓)TextInputLayout 使用及其
  6. 【android】 监听去电和来电电话状态
  7. Android下intent的setdata、settype和set
  8. Android中ImageButton自定义按钮的按下效
  9. 朝花夕拾----新组件的学习和使用
  10. Android(安卓)零碎