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
相关产品推荐
相关产品推荐

