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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 01:40:55