蓝牙是手机和智能硬件通信常用的方式,蓝牙通信可分为传统蓝牙和低功耗蓝牙(BLE)。其中BLE的连接断开等操作可以通过Android SDK中提供的API进行操作,而传统蓝牙部分SDK并没有提供相关的API进行连接断开,只能用户自己通过手机的设置界面连接蓝牙。
那么我们如何做到在代码中自动连接传统蓝牙呢?我们可以利用反射调用Android中的私有API进行连接断开操作。
0x01 声明变量
private BluetoothDevice device;
private BluetoothAdapter blueToothAdapter;
private BluetoothHeadset mBluetoothHeadset;
private BluetoothA2dp mBluetoothA2dp;
0x02 初始化变量
blueToothAdapter = BluetoothAdapter.getDefaultAdapter();
blueToothAdapter.getProfileProxy(this, new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null;
}
}
},BluetoothProfile.HEADSET);
blueToothAdapter.getProfileProxy(this, new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.A2DP){
mBluetoothA2dp = (BluetoothA2dp) proxy;
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.A2DP){
mBluetoothA2dp = null;
}
}
},BluetoothProfile.A2DP);
0x03 连接HFP
private void connect() {
if (mBluetoothHeadset == null) {
return;
}
if (device == null) {
return;
}
try {
Log.e(TAG, "connect" + device.getName() + device.getAddress());
Method connect = mBluetoothHeadset.getClass().getDeclaredMethod("connect", BluetoothDevice.class);
connect.setAccessible(true);
connect.invoke(mBluetoothHeadset, device);
} catch (Exception e) {
Log.e(TAG, "connect exception:" + e);
e.printStackTrace();
}
}
0x04 连接A2DP
private void connect2() {
if (mBluetoothA2dp == null) {
return;
}
if (device == null) {
return;
}
try {
Log.d(TAG, "connect" + device.getName() + device.getAddress());
Method connect = mBluetoothA2dp.getClass().getDeclaredMethod("connect", BluetoothDevice.class);
connect.setAccessible(true);
connect.invoke(mBluetoothA2dp, device);
} catch (Exception e) {
Log.e(TAG, "connect exception:" + e);
e.printStackTrace();
}
}
0x05 断开连接
同时断开HFP和A2DP。
private void disconnect() {
if (mBluetoothHeadset == null) {
return;
}
if (device == null) {
return;
}
try {
Log.d(TAG, "disconnect" + device.getName());
Method connect = mBluetoothHeadset.getClass().getDeclaredMethod("disconnect", BluetoothDevice.class);
connect.setAccessible(true);
connect.invoke(mBluetoothHeadset, device);
} catch (Exception e) {
Log.e(TAG, "disconnect exception:" + e);
e.printStackTrace();
}
if (mBluetoothA2dp == null) {
return;
}
try {
Log.d(TAG, "disconnect" + device.getName());
Method connect = mBluetoothA2dp.getClass().getDeclaredMethod("disconnect", BluetoothDevice.class);
connect.setAccessible(true);
connect.invoke(mBluetoothA2dp, device);
} catch (Exception e) {
Log.e(TAG, "disconnect exception:" + e);
e.printStackTrace();
}
}
至此所有关键代码都已经完成,在使用过程中,可能会有出现连接不上的问题。实验证明先断开然后在分别连接HFP和A2DP会稳定很多。