Android蓝牙控制设备无响应:修改MTU后sendCommands仍失效求助
问题排查与修复建议
核心问题:MTU修改未成功
从你提供的日志New MTU:256 mtu ,status : 1可以看出,MTU请求的状态码是1,而Android BluetoothGatt中GATT_SUCCESS的状态码为0,这意味着你的MTU修改请求实际失败了,这是设备无响应的根本原因。
代码中的关键错误点
1. onMtuChanged回调的无限循环逻辑
你的onMtuChanged方法存在严重逻辑错误:在MTU变更回调中再次调用gatt.requestMtu(mtu),会导致无限循环发起MTU请求,直接干扰正常协商流程,引发MTU修改失败。
错误代码片段:
@Override public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { super.onMtuChanged(gatt, mtu, status); if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { return; } // 错误:此处重复发起MTU请求,导致无限循环 gatt.requestMtu(mtu); Log.i(TAG, "New MTU: " + mtu + " , Status: " + status + " , Succeed: " + (status == gatt.GATT_SUCCESS)); }
修复后的onMtuChanged:
@Override public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { super.onMtuChanged(gatt, mtu, status); if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { return; } Log.i(TAG, "New MTU: " + mtu + " , Status: " + status + " , Succeed: " + (status == gatt.GATT_SUCCESS)); // 仅在MTU修改成功后,执行命令发送逻辑 if (status == BluetoothGatt.GATT_SUCCESS) { try { sendCommands(gatt); } catch (JSONException e) { e.printStackTrace(); } } else { // 处理修改失败,可重试一次 gatt.requestMtu(256); } }
2. sendCommands方法的不合理设计
- 固定延迟不可靠:通过
postDelayed延迟10秒发送命令的方式完全依赖经验值,无法保证MTU协商完成后再发送指令,可能导致命令在MTU未生效时就被发出。 - 重复发起MTU请求:方法内再次调用
gatt.requestMtu(256)属于冗余操作,会干扰之前的协商流程。 - 无写入结果校验:调用
gatt.writeCharacteristic后,未通过回调确认写入是否成功,无法排查命令是否真的送达设备。
修复后的sendCommands:
public void sendCommands(BluetoothGatt gatt) throws JSONException { if (gatt == null) { return; } if (BluetoothProfile.STATE_CONNECTED != gatt.getConnectionState()) { return; } List<BluetoothGattService> gattServices = gatt.getServices(); for (BluetoothGattService service : gattServices) { String serviceUUID = service.getUuid().toString(); if (serviceUUID.equalsIgnoreCase(SERVICE_GUID)) { List<BluetoothGattCharacteristic> gattCharacteristics = service.getCharacteristics(); for (BluetoothGattCharacteristic characteristic : gattCharacteristics) { final String uuid = characteristic.getUuid().toString(); if (uuid.equalsIgnoreCase(TX_CHAR_GUID)) { String jsonString = "{\"i\":1,\"v\":1,\"t\":8,\"s\":\"dbri\",\"n\":50}"; byte[] payload = jsonString.getBytes(Charsets.UTF_8); characteristic.setValue(payload); // 写入特征,等待回调确认结果 gatt.writeCharacteristic(characteristic); return; // 避免重复写入 } } } } }
3. 补充特征写入结果回调
需要重写onCharacteristicWrite来确认命令发送状态:
@Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicWrite(gatt, characteristic, status); if (status == BluetoothGatt.GATT_SUCCESS) { Log.i(TAG, "命令发送成功"); } else { Log.e(TAG, "命令发送失败,状态码:" + status); } }
额外排查点
- 确认设备支持256的MTU:部分BLE设备最大MTU小于256,强行请求会失败,可尝试降低至200测试。
- 检查权限状态:确保
BLUETOOTH_CONNECT权限已被用户授予,避免权限问题导致操作失败。
内容的提问来源于stack exchange,提问作者Hayjyo
相关产品推荐
相关产品推荐

