参考依赖库:
implementation 'cn.com.superLei:blelibrary:3.0.0'
GitHub - zemoLee/HeadSetConnectA2DP: 蓝牙耳机连接A2DP音频
总结关于蓝牙A2DP 操作的一些相关方法和接口:
1. 设置获取A2dp对象
/**
* 服务监听器,通过绑定服务获取BluetoothA2dp对象
*/
private BluetoothA2dp mBluetoothA2dp;
public class MyServiceListener implements BluetoothProfile.ServiceListener {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
LoggerUtils.d(TAG + "onServiceConnected()");
/**
* use reflect method to get the Hide method "connectToDevice" in BluetoothA2DP
*/
if (profile == BluetoothProfile.A2DP) {
mBluetoothA2dp = (BluetoothA2dp) proxy;
}
}
@Override
public void onServiceDisconnected(int profile) {
LoggerUtils.d(TAG + "onServiceDisconnected " + profile);
if (profile == BluetoothProfile.A2DP) {
mBluetoothA2dp = null;
}
}
sBluetoothAdapter.getProfileProxy(context, new MyServiceListener(), BluetoothProfile.A2DP);

2. 判断A2DP link 是否已建立
if (sBluetoothAdapter.getProfileConnectionState(BluetoothProfile.A2DP) == BluetoothProfile.STATE_CONNECTED) {
return true;
}
3. 获取连接的A2DP 设备
public BluetoothDevice getConnectedA2dp(BluetoothA2dp mBluetoothA2dp) {
LoggerUtils.d(TAG + "getconnectedA2dp()");
List<BluetoothDevice> connectedDevices = mBluetoothA2dp.getConnectedDevices();
if (connectedDevices != null && connectedDevices.size() > 0) {
BluetoothDevice device = connectedDevices.get(0);
return device;
}
return null;
}

4. 蓝牙设备扫描
BluetoothAdapter sBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // 获取蓝牙适配器
sBluetoothAdapter.isEnabled() // 判断手机蓝牙是否开启
sBluetoothAdapter.enable(); // 尝试开机手机蓝牙
sBluetoothAdapter.startDiscovery(); // 开启扫描蓝牙设备
sBluetoothAdapter.cancelDiscovery(); // 停止扫描蓝牙设备
5. 注册监听蓝牙状态改变的一些通知
public void register() {
LoggerUtils.d(TAG + "register()");
IntentFilter filter = new IntentFilter();
//扫描action
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
//配对监听
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
// filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);//A2dp状态改变
MyApp.getContext().registerReceiver(MYBroadcast, filter);
}
6. 监听回调
BroadcastReceiver MYBroadcast = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
/**
* 开始扫描
*/
if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
if (mDiscoveryListener == null) return;
bluetoothDevices.clear();
LoggerUtils.d(TAG + "ACTION_DISCOVERY_STARTED");
mDiscoveryListener.onScanStart();
/**
* 扫描结束
*/
} else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
if (mDiscoveryListener == null) return;
mDiscoveryListener.onScanFinish();
discoveryTimes--;
if (bluetoothDevices.size() == 0 && discoveryTimes > 0) {
LoggerUtils.d(TAG + "==================");
startDiscovery(true);
} else {
discoveryTimes = 3;
}
LoggerUtils.d(TAG + "ACTION_DISCOVERY_FINISHED");
/**
* 发现设备
*/
} else if (action.equals(BluetoothDevice.ACTION_FOUND)) {
if (mDiscoveryListener == null) return;
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDiscoveryListener.onDeviceFound(device);
bluetoothDevices.add(device);
LoggerUtils.d(TAG + "ACTION_FOUND: " + device.getAddress() + "\n" + device.getName());
/**
* 绑定状态改变
*/
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {//绑定状态监听
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
connectToDevice();
}
/**
* 连接状态改变
*/
} else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
LoggerUtils.d(TAG + "ACTION_CONNECTION_STATE_CHANGED");
/**
* spp连接
*/
} else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
LoggerUtils.d(TAG + "ACTION_ACL_CONNECTED");
/**
* spp断开连接
*/
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
LoggerUtils.d(TAG + "ACTION_ACL_DISCONNECTED");
/**
* 断开请求
*/
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED)) {
LoggerUtils.d(TAG + "ACTION_ACL_DISCONNECT_REQUESTED");
/**
* A2dp
*/
} else if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, 0);
/**
* A2dp连接成功
*/
if (state == BluetoothA2dp.STATE_CONNECTED) {
if (mBluetoothA2dp == null) return;
mLastBluetoothDevice = sBluetoothDevice;
sBluetoothDevice = getConnectedA2dpDevice(mBluetoothA2dp);
LoggerUtils.d(TAG + "onReceive: " + "A2dp的连接成功");
notifyConnectSuccess();
// if(sJIElIManager != null && sJIElIManager.getFilePathItemList())
/**
* A2dp断开
*/
} else if (state == BluetoothA2dp.STATE_DISCONNECTED) {
LoggerUtils.d(TAG + "onReceive: " + "A2dp断开");
notifyDisconnect();
}
}
}
};
7. 连接蓝牙
public void connectToDevice() {
LoggerUtils.d(TAG + "connectToDevice()");
if (sBluetoothDevice == null) return;
if (getBluetoothType() == 2) {
LoggerUtils.d(TAG + "杰里蓝牙连接");
switch (sBluetoothDevice.getBondState()) {
case BluetoothDevice.BOND_NONE:
boolean returnValue = createBond();//配对
if (returnValue) {
LoggerUtils.d(TAG + "配对成功");
} else {
LoggerUtils.d(TAG + "配对失败");
}
break;
case BluetoothDevice.BOND_BONDED:
try {
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(DUUID);
Method method_connect = clazz.getMethod("connect", BluetoothDevice.class);
Boolean BooleanValue = (Boolean) method_connect.invoke(mBluetoothA2dp, mBluetoothDevice);
}
} catch (Exception e) {
e.printStackTrace();
LoggerUtils.d(TAG + "A2dp连接异常,reason = " + e.getCause());
}
break;
}
}
}
8. 绑定设备
public boolean createBond() {
try {
Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(sBluetoothDevice);
return returnValue;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return false;
}
9, 断开蓝牙
try {
Method method_disconnect = clazz.getMethod("disconnect", BluetoothDevice.class);
Boolean BooleanValue = (Boolean) method_disconnect.invoke(mBluetoothA2dp, mBluetoothDevice);
} catch (Exception e) {
e.printStackTrace();
LoggerUtils.d(TAG + "断开A2dp连接异常,reason = " + e.getMessage());
}
if (socket != null) {
try {
socket.close();
socket = null;
LoggerUtils.d(TAG + "断开spp socket成功");
} catch (IOException e) {
e.printStackTrace();
LoggerUtils.d(TAG + "断开spp socket异常,reason = " + e.getCause());
}
}
10. 解绑定设备
public boolean removeBond() { try { Method removeBondMethod = BluetoothDevice.class.getMethod("removeBond"); Boolean returnValue = (Boolean) removeBondMethod.invoke(sBluetoothDevice); return returnValue.booleanValue(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return false; }

参考链接:android: 建立和断开a2dp link 相关方法总结 - 夜行过客 - 博客园 (cnblogs.com)