Android 实现蓝牙录音

#Android 实现蓝牙录音

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

app的界面
1

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

具体的实现过程:
这里封装了打开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中声明。
下面是蓝牙录音存储相关的权限:

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

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

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

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

峥嵘life

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值