You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android设备BLE writeCharacteristic始终返回false问题求助

Android BLE writeCharacteristic返回false且无回调的问题排查与修复

核心问题分析

从你的代码来看,导致writeCharacteristic()返回false且不触发onCharacteristicWrite()的关键原因有以下几点:

  • 未执行实际写入操作:当前调用的自定义writeCharacteristic()方法仅设置了特征值,完全没有调用gatt.writeCharacteristic()来发起BLE写入请求,这是最根本的问题。
  • 参数传反:调用writeCharacteristic(uuid, String.valueOf(gattCharacteristic.getUuid()),...)时,把服务UUID和特征UUID的参数顺序传反了,导致无法正确获取目标服务和特征。
  • 异常处理失效:自定义方法中characteristic == null时仅创建了异常但未抛出,代码继续执行空对象操作,无任何实际效果。
  • 潜在的MTU限制:你构造的JSON payload长度大概率超过了BLE默认MTU(23字节),超出部分会导致写入失败。
  • 权限与写入类型不匹配:Android 12+需要BLUETOOTH_CONNECT权限,且写入类型需与特征支持的属性匹配。

修复方案与代码示例

修正后的写入方法

直接复用你注释掉的正确流程,补充MTU检查、权限验证和异常处理:

public void writeCommand(BluetoothGatt gatt, int bright_value) {
    if (bluetoothGatt == null) return;

    // 验证Android 12+所需的蓝牙连接权限
    if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
        Log.e("BLE", "缺少BLUETOOTH_CONNECT权限,无法执行写入");
        return;
    }

    // 遍历服务找到目标特征
    List<BluetoothGattService> gattServices = gatt.getServices();
    for (BluetoothGattService service : gattServices) {
        if (service.getUuid().toString().equalsIgnoreCase(SERVICE_GUID)) {
            BluetoothGattCharacteristic targetChar = service.getCharacteristic(UUID.fromString(TX_CHAR_GUID));
            if (targetChar == null) {
                Log.e("BLE", "未找到目标特征UUID:" + TX_CHAR_GUID);
                continue;
            }

            String jsonString = "{\"i\": 1, \"v\": 1, \"t\": 8, \"s\": \"dbri\", \"n\": "+ bright_value +"}";
            byte[] payload = jsonString.getBytes();

            // 检查当前MTU是否足够容纳payload(减去3字节BLE协议头)
            int currentMtu = gatt.getMtu();
            if (payload.length > currentMtu - 3) {
                Log.i("BLE", "Payload过长,请求MTU扩容至:" + (payload.length + 3));
                gatt.requestMtu(payload.length + 3);
                // 在onMtuChanged回调中重新执行写入
                return;
            }

            // 根据特征支持的属性设置写入类型
            if ((targetChar.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0) {
                targetChar.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
            } else {
                targetChar.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
            }

            // 设置特征值并执行写入
            if (targetChar.setValue(payload)) {
                boolean writeStatus = gatt.writeCharacteristic(targetChar);
                Log.i("BLE", "写入请求提交状态:" + writeStatus);
            } else {
                Log.e("BLE", "设置特征值失败");
            }
            break;
        }
    }
}

补充GattCallback回调处理

需要在BluetoothGattCallback中添加MTU协商和写入结果的处理:

@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
    super.onMtuChanged(gatt, mtu, status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        Log.i("BLE", "MTU协商成功,当前MTU:" + mtu);
        // 重新发起写入(需保存bright_value变量或重新传入)
        writeCommand(gatt, yourSavedBrightValue);
    } else {
        Log.e("BLE", "MTU协商失败,状态码:" + status);
    }
}

@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    super.onCharacteristicWrite(gatt, characteristic, status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        Log.i("BLE", "特征写入成功");
    } else {
        Log.e("BLE", "特征写入失败,状态码:" + status);
    }
}

额外注意事项

  • 确保BLE连接处于活跃状态,未断开或重连中。
  • 避免同时发起多个BLE操作(如同时读特征+写特征),BLE操作需要串行执行。
  • 验证自定义开发板的BLE特征属性,确认其支持你设置的写入类型。

内容的提问来源于stack exchange,提问作者Hayjyo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 20:49:51