Android 蓝牙开发A2DP基本功能

书史足自悦,安用勤与劬。这篇文章主要讲述Android 蓝牙开发A2DP基本功能相关的知识,希望能为你提供帮助。
转载请注明出处: 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< BluetoothDevice> 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_OFF0
PRIORITY_ON100
PRIORITY_AUTO_CONNECT1000
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 获取连接设备列表
//返回值类型List< BluetoothDevice> mA2dp.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); } } };

有问题欢迎交流指正。
连接小demo: http://www.demodashi.com/demo/14624.html
欢迎扫一扫关注我的微信公众号, 定期推送优质技术文章:
【Android 蓝牙开发A2DP基本功能】
Android 蓝牙开发A2DP基本功能

文章图片


    推荐阅读