Qt 5.14.2 Android端BLE连接异常 无法发送数据问题咨询
问题说明
你实现的BLE收发应用在Windows平台运行正常,Android平台在服务发现阶段触发QLowEnergyController::ConnectionError后直接断连,无法执行数据发送逻辑。
代码存在的核心问题
- QLowEnergyController创建参数不兼容Android平台
你在调用QLowEnergyController::createCentral时传入了第二个参数QBluetoothLocalDevice().address()指定本地蓝牙地址,该参数仅在桌面端(Windows/Linux/macOS)有效,Android系统的BLE栈不支持应用指定本地适配器地址,传参会导致底层服务发现流程异常,连接在发现服务阶段被系统主动断开,和你日志里的现象完全吻合。 - UUID匹配逻辑存在跨平台兼容问题
你定义的UUID字符串带大括号,且所有UUID匹配都通过toString()转字符串后和宏定义比较。不同平台Qt的BLE后端返回的UUID字符串格式存在差异(可能不带大括号、大小写不一致),直接导致服务、特征匹配失败。 - 异步操作时序错误
写入CCCD通知使能描述符是异步操作,你在写入描述符后立刻调用requestData()发送数据,Android端大部分BLE设备会在通知配置完成前拒绝接收数据,甚至主动断开连接。 - (次要)Android高版本权限缺失风险
你的日志仅校验了位置权限,若targetSdkVersion >= 31(Android 12+),还需要申请BLUETOOTH_SCAN、BLUETOOTH_CONNECT权限,否则会出现随机连接失败问题。
修复步骤
- 修正控制器创建逻辑,移除Android不支持的本地地址参数:
// 原代码 // m_controller.reset(QLowEnergyController::createCentral(QBluetoothAddress(macAddress), QBluetoothLocalDevice().address())); // 修改为 m_controller.reset(QLowEnergyController::createCentral(QBluetoothAddress(macAddress))); - 修正UUID定义与匹配逻辑,去掉大括号,直接用QBluetooth对象比较,不要转字符串:
// 宏定义去掉大括号 #define SERVICE_UUID "49535343-fe7d-4ae5-8fa9-9fafd205e455" #define SERVICE_CHARACTERISTIC_TX_UUID "49535343-1e4d-4bd9-ba61-23c647249616" // 服务发现匹配修改 void Communicator::onServiceDiscovered(const QBluetoothUuid& service) { if(service == QBluetoothUuid(SERVICE_UUID)) m_serviceDiscovered = true; } // 特征查找匹配修改 if(characteristic.uuid() == QBluetoothUuid(SERVICE_CHARACTERISTIC_TX_UUID)) { // 原有特征处理逻辑 } // 特征变化判断修改 if(info.uuid() != m_writeCharacteristic.uuid()) return; - 修正异步操作时序,增加通知就绪标记,等CCCD描述符写入完成后再发送数据:
- 类成员增加
bool m_notificationReady = false; - 在已有的descriptorWritten信号回调中增加判断:
QObject::connect(m_service.data(), &QLowEnergyService::descriptorWritten, this, [this](const QLowEnergyDescriptor &info, const QByteArray &value) { qDebug() << "DESCRIPTOR WRITTEN -> UUID:" << info.uuid().toString() << "VALUE:" << value; if(info.uuid() == QBluetoothUuid::ClientCharacteristicConfiguration && value == QByteArray::fromHex("0100")) { m_notificationReady = true; requestData(); } }); - 移除
onServiceStateChanged中ServiceDiscovered状态下直接调用的requestData(),只保留searchCharacteristics(),等描述符写入完成后再触发数据请求。
- 类成员增加
- 适配Android 12+权限,在AndroidManifest.xml中补充权限声明,同时在应用运行时动态申请:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
额外优化建议
如果修复后仍存在写入失败问题,可先强制使用WriteWithResponse模式测试,部分Android BLE栈对无响应写入的兼容性较差。
内容的提问来源于stack exchange,提问作者Fausto01
相关产品推荐
相关产品推荐

