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

Android11下BLE通信故障:mWriteCharacteristic为空无法发送数据至ESP32

Android 11设备BLE写入特性为null问题排查方案

1. 权限适配遗漏(Android 11专属)

Android 11(API 30)的BLE权限逻辑和Android 13存在差异,除了BLUETOOTH、BLUETOOTH_ADMIN,必须动态申请ACCESS_FINE_LOCATION权限——即使已完成BLE连接,服务发现、特性获取操作依然依赖该权限。

检查并补全权限配置:

  • 清单文件添加权限声明:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
  • 连接GATT前动态申请权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
    ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1001);
    return;
}

2. GATT服务发现时机错误

mWriteCharacteristic的初始化必须在BluetoothGattCallback的onServicesDiscovered回调触发后执行——连接GATT后,系统需要时间发现设备服务,提前调用service.getCharacteristic()会返回null。

修正特性初始化逻辑:

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        super.onServicesDiscovered(gatt, status);
        if (status == BluetoothGatt.GATT_SUCCESS) {
            // 在此处获取服务与特性
            BluetoothGattService targetService = gatt.getService(SERVICE_UUID);
            if (targetService != null) {
                mWriteCharacteristic = targetService.getCharacteristic(WRITE_CHARACTERISTIC_UUID);
                if (mWriteCharacteristic == null) {
                    Log.e(TAG, "写入特性未找到");
                }
            }
        }
    }
    // 其他回调实现...
};

// 连接GATT后必须主动调用服务发现
obj.mBluetoothGatt = device.connectGatt(context, false, obj.mGattCallback, BluetoothDevice.TRANSPORT_LE);
obj.mBluetoothGatt.discoverServices();

3. UUID匹配问题

检查代码中WRITE_CHARACTERISTIC_UUID是否与ESP32端完全一致,重点注意:

  • 大小写:Android的UUID区分大小写,ESP32端如果用大写,代码需保持一致
  • 长度匹配:ESP32常用16位短UUID(如0xFFE1),Android端需补全为128位标准格式(如0000ffe1-0000-1000-8000-00805f9b34fb),反之亦然

示例正确UUID写法:

// ESP32端为16位UUID 0xFFE1时,Android端对应写法
public static final UUID WRITE_CHARACTERISTIC_UUID = UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb");

4. GATT连接参数适配

Android 11对BLE连接参数兼容性要求更严格,尝试调整连接参数:

  • 将connectGatt的autoConnect参数改为true(优化连接稳定性)
  • 确保TRANSPORT_LE参数在全版本生效(你已适配,可确认无版本分支遗漏)

调整后的连接代码:

obj.mBluetoothGatt = device.connectGatt(context, true, obj.mGattCallback, BluetoothDevice.TRANSPORT_LE);

5. 写入特性属性验证

确认ESP32端的写入特性是否开启了正确属性:必须包含PROPERTY_WRITE或PROPERTY_WRITE_NO_RESPONSE。若属性缺失,Android端无法识别为可写入特性,getCharacteristic()会返回null。

可通过通用BLE工具(如nRF Connect)查看ESP32特性的属性列表,确认写入权限是否正常配置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:08:15