A2DP简介
A2DP(Advanced Audio Distribution Profile):高质量音频数据传输协议。定义了传送单声道或立体声等高质量音频(区别于蓝牙SCO链路上传输的普通语音)信息的协议和过程。A2DP典型应用是将音乐播放器的音频数据发送到耳机或者音箱。
开发流程
1.获取蓝牙适配器
mAdapter = BluetoothAdapter.getDefaultAdapter();
2.获取A2DP代理
不能直接获取proxy,只能在onServiceConnected()回调中获取
mAdapter.getProfileProxy(context, new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
mA2dp = (BluetoothA2dp) proxy;
}
@Override
public void onServiceDisconnected(int profile) {
}
}, BluetoothProfile.A2DP);
3.注册蓝牙接收广播
开启搜索设备后,搜索结果通过广播传输
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
4.搜索设备
mAdapter.startDiscovery();
5.获取搜索结果
从BluetoothDevice.ACTION_FOUND广播中获取
6.连接设备
mA2dp.getClass().getMethod("connect",BluetoothDevice.class).invoke(mA2dp, device);
3.代码实现
public class A2DPManager {
public static final String TAG = A2DPManager.class.getName();
private static A2DPManager mManager;
private BluetoothAdapter mAdapter;
private BluetoothA2dp mA2dp;
private List result;
public static A2DPManager getInstance(Context context) {
if (mManager == null) {
mManager = new A2DPManager(context);
}
return mManager;
}
private A2DPManager(Context context) {
result = new ArrayList<>();
mAdapter = BluetoothAdapter.getDefaultAdapter();
mAdapter.getProfileProxy(context, new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
mA2dp = (BluetoothA2dp) proxy;
}
@Override
public void onServiceDisconnected(int profile) {
}
}, BluetoothProfile.A2DP);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
context.registerReceiver(mReceiver,intentFilter);
}
/**
* 打开蓝牙
*/
public void enableA2DP() {
if (!mAdapter.isEnabled()) {
mAdapter.enable();
}
}
/**
* 关闭蓝牙
*/
public void disableA2DP() {
if (mAdapter.isEnabled()) {
mAdapter.disable();
}
}
public void discovery() {
if (mAdapter.isDiscovering()) {
mAdapter.cancelDiscovery();
}
if (!result.isEmpty()) {
result.clear();
}
if (mAdapter.isEnabled()) {
mAdapter.startDiscovery();
} else {
//如果刚打开蓝牙,蓝牙还没有初始化成功,需要等待蓝牙初始化成功后才能搜索蓝牙设备
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mAdapter.startDiscovery();
}
}, 1000);
}
}
/**
* 连接设备
*
* @param device
*/
public void connect(BluetoothDevice device) {
if (device == null) {
return;
}
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
//如果设备未配对,先进行配对,收到配对成功广播后,连接设备
pair(device);
} else {
if (mA2dp != null) {
if (mA2dp.getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) {
try {
boolean connect = (boolean) mA2dp.getClass()
.getMethod("connect", BluetoothDevice.class)
.invoke(mA2dp, device);
Log.d(TAG, "connect:" + connect);
} catch (Exception e) {
e.printStackTrace();
}
} else {
Log.d(TAG, "设备已经连接");
}
}
}
}
/**
* 断开设备
*
* @param device
*/
public boolean disConnect(BluetoothDevice device) {
if (device == null) {
return false;
}
boolean disConnect = false;
if (mA2dp != null) {
if (mA2dp.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED) {
try {
disConnect = (boolean) mA2dp.getClass()
.getMethod("disconnect", BluetoothDevice.class)
.invoke(mA2dp, device);
Log.d(TAG, "disconnect:" + disConnect);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return disConnect;
}
/**
* 蓝牙配对
*
* @param device
*/
public void pair(final BluetoothDevice device) {
HandlerThread handlerThread = new HandlerThread("pair");
handlerThread.start();
Handler pairHandler = new Handler(handlerThread.getLooper());
pairHandler.post(new Runnable() {
@Override
public void run() {
try {
Method method = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
BluetoothSocket socket = (BluetoothSocket) method.invoke(device, 1);
socket.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* 获取已经配对的设备
*/
public Set getBondeDevices() {
return mAdapter.getBondedDevices();
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "action:" + action);
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (action.equals(BluetoothDevice.ACTION_FOUND)) {
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
if (device.getName() != null) {
result.add(device);
Log.d(TAG, "deviceName:" + device.getName());
}
}
} else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
switch (device.getBondState()) {
case BluetoothDevice.BOND_BONDING:
Log.d(TAG, "正在配对");
break;
case BluetoothDevice.BOND_BONDED:
Log.d(TAG, "完成配对");
A2DPManager.getInstance(context).connect(device);
break;
case BluetoothDevice.BOND_NONE:
Log.d(TAG, "取消配对");
break;
default:
break;
}
} else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
Log.d(TAG, "搜索完成");
result.addAll(A2DPManager.getInstance(context).getBondeDevices());
EventBus.getDefault().post(result);
} else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
Log.d(TAG, "状态变化");
}
}
};
}