1. 蓝牙相关权限(GPS)要先于BluetoothAdapter获取
我的所有蓝牙处理都放在一个Helper里,因此在Application里,我初始化了BluetoothAdapter,当权限未授予时,我授予权限后,搜索蓝牙则收不到蓝牙广播;于是我想着在权限打开后,重新初始化BluetoothAdapter试试,结果发现也不行;BluetoothAdapter只能在权限满足后再初始化才有效;
2. 弱机型的适配;
有一些机型的蓝牙芯片非常差,比如三星的A7;差主要体现在刚连接后,发送指令容易失败,于是做了一套检测机制来避免这个问题
BluetoothHelper.getInstance().connectBluetooth(address, (gatt, connect) -> {
//收到成功回调时,开始检测
if (connect) {
startCheck();
}
});
startCheck()
public void startCheck() {
SUtils.saveBooleanData(context, SharePreConstant.CHECK_STABLE_SUC + address, false);
sendCheck();
}
在onServicesDiscovered回调后,存储 (SharePreConstant.CHECK_STABLE_SUC + address)的状态;如果为true,则发送指令:
private void sendCheck() {
boolean isBleStable = SUtils.getBooleanData(BaseApplication.getContext(), SharePreConstant.CHECK_BLE_STABLE_SUC + address);
//弱蓝牙芯片迟迟不给service回调,没办法,只能断开重新连接
if (!isBleStable) {
tryCount++;
if (tryCount > 5) {
tryCount = 0;
BluetoothHelper.getInstance().disconnectBle(true, address);
safeConnect();
return;
}
Logs.i("蓝牙还没有就绪");
myHandler.postDelayed(() -> sendCheck(), 500);
return;
}
Logs.i("蓝牙已经就绪");
SUtils.saveBooleanData(BaseApplication.getContext(), SharePreConstant.CHECK_BLE_STABLE_SUC + address, false);
//如果当前蓝牙不在dfu状态下则发送验证指令,我把获取电量当作验证与心跳指令
if (!BluetoothHelper.getInstance().checkDfu(bluetoothGatt.getDevice().getName())) {
myHandler.postDelayed(() -> {
Logs.empty();
byte[] checkBattery = {BleCommand.GET_BATTERY};
BluetoothHelper.getInstance().writeCharacteristicByAddress(checkBattery, address, true);
checkSuc();
}, 200);
}
}
当蓝牙返回BleCommand.GET_BATTERY的值时,则判断为成功:
/**
* 检查是否成功
*/
private void checkSuc() {
boolean isChecked = SUtils.getBooleanData(context, SharePreConstant.CHECK_STABLE_SUC + address);
if (isChecked) {
myHandler.sendEmptyMessageDelayed(MSG_CANCEL_DIALOG, 300);
myHandler.sendEmptyMessageDelayed(MSG_BLE_CONNECTED, 500);
} else {
tryCount++;
//如果多次未收到消息,则断开,重新连接
if (tryCount > 5) {
tryCount = 0;
BluetoothHelper.getInstance().disconnectBle(true, address);
safeConnect();
return;
}
sendCheck();
}
}
蓝牙app外包请找我:505709544