安卓APK开发:如何通过MAC地址断开已连接蓝牙设备?
解决蓝牙耳机断开/连接问题的正确方案
你的代码用了BluetoothGatt,这是给BLE(低功耗蓝牙)设备设计的,而蓝牙耳机属于经典蓝牙,走的是A2DP(音频)/HFP(通话)协议,这套逻辑完全不适用,所以才没有效果。下面是针对经典蓝牙设备的正确实现方式:
1. 申请必要权限
根据Android版本不同,权限要求有差异,先在AndroidManifest.xml里声明基础权限:
<!-- Android 11及以下权限 --> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" /> <!-- Android 12+权限 --> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
Android 12+还需要动态申请BLUETOOTH_CONNECT权限,否则无法操作蓝牙设备。
2. 实现断开/连接逻辑
核心是通过BluetoothA2dp(音频协议代理)来操作设备,以下是完整代码示例:
private BluetoothA2dp mA2dpProxy; private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // 初始化A2DP协议代理 private void initA2dpProxy() { if (mBluetoothAdapter == null) { // 设备不支持蓝牙,直接返回 return; } mBluetoothAdapter.getProfileProxy(this, new BluetoothProfile.ServiceListener() { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { if (profile == BluetoothProfile.A2DP) { mA2dpProxy = (BluetoothA2dp) proxy; } } @Override public void onServiceDisconnected(int profile) { if (profile == BluetoothProfile.A2DP) { mA2dpProxy = null; } } }, BluetoothProfile.A2DP); } // 断开指定MAC地址的蓝牙耳机 public void disconnectDevice(String macAddress) { if (mA2dpProxy == null) { initA2dpProxy(); // 可添加延迟重试逻辑,或提示用户等待初始化完成 return; } BluetoothDevice targetDevice = mBluetoothAdapter.getRemoteDevice(macAddress); // 检查设备是否处于连接状态 if (mA2dpProxy.getConnectionState(targetDevice) == BluetoothProfile.STATE_CONNECTED) { mA2dpProxy.disconnect(targetDevice); } } // 连接指定MAC地址的蓝牙耳机 public void connectDevice(String macAddress) { if (mA2dpProxy == null) { initA2dpProxy(); return; } BluetoothDevice targetDevice = mBluetoothAdapter.getRemoteDevice(macAddress); if (mA2dpProxy.getConnectionState(targetDevice) == BluetoothProfile.STATE_DISCONNECTED) { mA2dpProxy.connect(targetDevice); } } // 页面销毁时释放代理资源 @Override protected void onDestroy() { super.onDestroy(); if (mBluetoothAdapter != null && mA2dpProxy != null) { mBluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, mA2dpProxy); mA2dpProxy = null; } }
3. 额外注意事项
- 操作前先检查蓝牙是否开启:
mBluetoothAdapter.isEnabled(),未开启可引导用户跳转到蓝牙设置页面 - 如果需要处理通话场景,还可以同时初始化
BluetoothHeadset(HFP协议)代理,断开时同时处理两个协议 - Android 12+必须先动态申请
BLUETOOTH_CONNECT权限,否则会抛出权限异常
内容的提问来源于stack exchange,提问作者Pavlin Petkov
相关产品推荐
相关产品推荐

