转载请注明出处:http://blog.csdn.net/vnanyesheshou/article/details/71713786

本文主要是Android做为Audio Source端,A2DP的基本操作:包括连接、断开连接、设置优先级、获取优先级、获取A2DP连接状态、获取A2DP连接的设备列表等功能。


1 简介

A2DP全名是Advanced Audio Distribution Profile,高质量音频数据传输的协议,其定义里了传送单声道或立体声等高质量音频(区别于蓝牙SCO链路上传输的普通语音)信息的协议和过程。A2DP的典型应用是将音乐播放器的音频数据发送到耳机或音箱。
A2DP定义了两种角色:

Audio Source(音频源) 音频的输入端对音频数据进行编码,发送到Sink端。
Audio Sink(音频接收器) 接收到音频数据后,进行解码操作还原出音频。


2 A2DP profile

要想操作A2DP相关,首先要获取A2DP代理对象,获取代理对象的方法比较简单,如下:

mBtAdapter = BluetoothAdapter.getDefaultAdapter();if(!mBtAdapter.isEnabled()){    //弹出对话框提示用户是后打开      Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);      startActivityForResult(enabler, 1);}//获取A2DP代理对象mBtAdapter.getProfileProxy(mContext, mListener, BluetoothProfile.A2DP);

getProfileProxy并不会直接返回A2DP代理对象,而是通过mListener中回调获取。

private ServiceListener mListener = new ServiceListener() {    @Override    public void onServiceDisconnected(int profile) {        if(profile == BluetoothProfile.A2DP){            mA2dp = null;        }    }    @Override    public void onServiceConnected(int profile, BluetoothProfile proxy) {        if(profile == BluetoothProfile.A2DP){            mA2dp = (BluetoothA2dp) proxy; //转换        }    }};

成功会回调mListener中的onServiceConnected函数,判断proflie是否为BluetoothProfile.A2DP,转换为BluetoothA2dp对象。通过代理对象即可进行A2DP的相关操作了。


3 A2DP操作

A2DP连接首先需要与蓝牙耳机进行配对,如何配对这里就不细说了。
我这里是连接到之前配对过的一个设备。设备名称为:

private final String BT_NAME = "QCY-QY7";

获取该设备,首先获取配对的蓝牙设备,然后遍历这些蓝牙设备,找出蓝牙名称符合条件的设备,就是要操作的设备,

//获取配对的蓝牙设备Set bondDevice = mBtAdapter.getBondedDevices();for(BluetoothDevice device:bondDevice){    //获取指定名称的设备    if(BT_NAME.equals(device.getName())){        mConnectDevice = device;    }}

mConnectDevice为要操作的设备。
1 A2DP连接

private void connectA2dp(BluetoothDevice device){    setPriority(mConnectDevice, 100); //设置priority    try {        //通过反射获取BluetoothA2dp中connect方法(hide的),进行连接。        Method connectMethod =BluetoothA2dp.class.getMethod("connect",                BluetoothDevice.class);        connectMethod.invoke(mA2dp, device);    } catch (Exception e) {        e.printStackTrace();    } }

BluetoothA2dp中的connect方法是hide的,不能直接访问,需要通过反射的机制获取该方法进行连接。连接成功后手机可以播放音乐,声音就会从蓝牙耳机出来。
2 断开连接

private void disConnectA2dp(BluetoothDevice device){    setPriority(mConnectDevice, 0);    try {        //通过反射获取BluetoothA2dp中connect方法(hide的),断开连接。        Method connectMethod =BluetoothA2dp.class.getMethod("disconnect",                BluetoothDevice.class);        connectMethod.invoke(mA2dp, device);    } catch (Exception e) {        e.printStackTrace();    }}

BluetoothA2dp中的disconnect方法也是hide的,与connect类似。
3 设置优先级

变量
PRIORITY_OFF 0
PRIORITY_ON 100
PRIORITY_AUTO_CONNECT 1000
PRIORITY_UNDEFINED -1

设置优先级是必要的,否则可能导致连接或断开连接失败等问题。

public void setPriority(BluetoothDevice device, int priority) {    if (mA2dp == null) return;    try {//通过反射获取BluetoothA2dp中setPriority方法(hide的),设置优先级        Method connectMethod =BluetoothA2dp.class.getMethod("setPriority",                 BluetoothDevice.class,int.class);        connectMethod.invoke(mA2dp, device, priority);    } catch (Exception e) {        e.printStackTrace();    }}

4 获取优先级

public int getPriority(BluetoothDevice device) {    int priority = 0;    if (mA2dp == null) return priority;    try {//通过反射获取BluetoothA2dp中getPriority方法(hide的),获取优先级        Method connectMethod =BluetoothA2dp.class.getMethod("getPriority",                 BluetoothDevice.class);        priority = (Integer) connectMethod.invoke(mA2dp, device);    } catch (Exception e) {        e.printStackTrace();    }    return priority;}

5 获取与某设备A2DP连接状态

mA2dp.getConnectionState(device);

6 获取连接设备列表

//返回值类型ListmA2dp.getConnectedDevices();

7 A2DP是否正在发送音频流

//返回值类型boolean,表示设备是否在通过A2DP发送音频流。mA2dp.isA2dpPlaying(device);

4 状态监听

通过广播接收者监听A2DP连接状态的改变,A2DP播放状态的改变。

private void initReceiver(){    //注册广播接收者监听状态改变    IntentFilter filter = new IntentFilter(BluetoothA2dp.            ACTION_CONNECTION_STATE_CHANGED);    filter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED);    registerReceiver(mReceiver, filter);}

广播接收者,通过intent获取状态值。

private BroadcastReceiver mReceiver = new BroadcastReceiver() {    @Override    public void onReceive(Context context, Intent intent) {        String action = intent.getAction();        Log.i(TAG,"onReceive action="+action);        //A2DP连接状态改变        if(action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)){            int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothA2dp.STATE_DISCONNECTED);            Log.i(TAG,"connect state="+state);        }else if(action.equals(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED)){            //A2DP播放状态改变            int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothA2dp.STATE_NOT_PLAYING);            Log.i(TAG,"play state="+state);        }    }};

有问题欢迎交流指正。

欢迎大家关注、评论、点赞
你们的支持是我坚持的动力。

欢迎关注我的微信公众号

更多相关文章

  1. Android(安卓)studio Mac版 安装及使用记录
  2. 代码流程分析二:Settings-蓝牙分析-搜索设备原理
  3. Android接收和发送短信的实现代码
  4. android MediaPlayer+Stagefright架构(音频)图解
  5. Androng,一个针对Android的Pong克隆
  6. 从头学Android之多媒体--使用MediaRecorder录制音频
  7. Android游戏开发系列教程第四讲(游戏音频)
  8. Qualcomm Snapdragon Debugger for Visual Studio 快速入门指南
  9. Android(安卓)USB Host 使用详解(U盘)(三)

随机推荐

  1. android输入框EditText输入银行卡,输入手
  2. android 开启自动旋转屏幕
  3. android操作sqlite3的blob字段,显示数据
  4. 新浪微博布局学习——活用Android的Relat
  5. android Pull方式解析xml文件
  6. Android拖动控件改变其位置
  7. Android中内容提供者ContentProvider实现
  8. android Http文件上传
  9. 【Android】手机地图功能——利用手机GPS
  10. android 6.0/7.1/9 默认打开 开发者选项