逆变器监测BLE安卓应用的Characteristic写入功能异常问题
BLE逆变器应用写入Characteristic异常排查与修复
核心问题分析
- 缺失
write方法实现:代码中多次调用write(String)但未提供具体实现,这是写入功能失效的直接原因。FastBle库的写入需通过异步回调完成,而非自定义无实现的方法。 - 特征选择不严谨:硬编码
servicesList.get(2)获取服务,易因设备服务顺序变化导致选择错误的特征;未验证目标特征是否具备写入权限。 - 数据格式不匹配:直接传入字符串可能不符合逆变器要求的字节格式(如Hex编码、固定长度数组),导致设备无法解析。
- 连续写入时序错误:用
Thread.sleep()强制等待的方式不符合BLE异步操作规范,前一次写入未完成就发起下一次,会导致写入失败。
代码修复建议
1. 实现标准写入方法
替换自定义的write方法,使用FastBle的异步写入回调:
private void writeData(String data) { // 替换为逆变器约定的服务UUID和写入特征UUID String targetServiceUuid = "你的目标服务UUID"; String writeCharUuid = "你的写入特征UUID"; // 根据设备要求转换数据格式,示例:转Hex字节数组 byte[] writeBytes = HexUtil.stringToHex(data).getBytes(); // 若设备支持UTF-8,也可使用:byte[] writeBytes = data.getBytes(StandardCharsets.UTF_8); BleManager.getInstance().write( bleDevice, targetServiceUuid, writeCharUuid, writeBytes, new BleWriteCallback() { @Override public void onWriteSuccess(int current, int total, byte[] justWrite) { Log.d(Tag, "写入成功: " + HexUtil.formatHexString(justWrite)); runOnUiThread(() -> { Toast.makeText(MainScreen.this, "写入成功", Toast.LENGTH_SHORT).show(); // 写入成功后更新UI,比如切换UPS状态文本 if (getString(R.string.ups_on).equals(upsStatus.getText().toString())) { upsStatus.setText(R.string.ups_off); } else { upsStatus.setText(R.string.ups_on); } }); } @Override public void onWriteFailure(BleException exception) { Log.e(Tag, "写入失败: " + exception.getDescription()); runOnUiThread(() -> Toast.makeText(MainScreen.this, "操作失败:" + exception.getDescription(), Toast.LENGTH_SHORT).show() ); } } ); }
2. 修正特征选择逻辑
通过UUID精准查找目标服务和特征,避免硬编码索引:
// 在setData()方法中替换原服务选择逻辑 String targetServiceUuid = "你的目标服务UUID"; String targetWriteCharUuid = "你的写入特征UUID"; BluetoothGatt gatt = BleManager.getInstance().getBluetoothGatt(bleDevice); for (BluetoothGattService service : gatt.getServices()) { if (service.getUuid().toString().equals(targetServiceUuid)) { BluetoothGattCharacteristic writeChar = service.getCharacteristic(UUID.fromString(targetWriteCharUuid)); if (writeChar != null) { // 验证特征是否支持写入 int properties = writeChar.getProperties(); if ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE) != 0 || (properties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0) { characteristicsList.add(writeChar); } else { Log.e(Tag, "该特征不支持写入"); } } break; } }
3. 修复按钮点击事件
移除基于返回值直接更新UI的逻辑,等待写入回调结果再处理:
upsStatus.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (!builderList.isEmpty()) { String input; if (getString(R.string.ups_on).equals(upsStatus.getText().toString())) { input = builderList.get(1).toString() + "%" + "OFF" + "%" + "END"; } else { input = builderList.get(1).toString() + "%" + "ON" + "%" + "END"; } // 调用标准写入方法 writeData(input); } } });
4. 修正连续写入逻辑
移除Thread.sleep(),在一次写入成功的回调中发起下一次写入:
// 示例:连续写入的正确姿势 writeData("hello sir"); // 在writeData的onWriteSuccess回调中发起下一次写入 @Override public void onWriteSuccess(int current, int total, byte[] justWrite) { Log.d(Tag, "写入成功: " + HexUtil.formatHexString(justWrite)); // 发起下一次写入 writeData("i am coder"); }
额外注意事项
- 确保已申请对应蓝牙权限:Android 12及以下需
BLUETOOTH、BLUETOOTH_ADMIN、ACCESS_FINE_LOCATION;Android 13+需BLUETOOTH_SCAN、BLUETOOTH_CONNECT。 - 开启FastBle日志:
BleManager.getInstance().enableLog(true),通过日志排查具体错误。 - 写入前确认设备处于连接状态,避免在断开连接时发起写入请求。
内容的提问来源于stack exchange,提问作者Javed Quantum
相关产品推荐
相关产品推荐

