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

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权限,否则会出现随机连接失败问题。
修复步骤
  1. 修正控制器创建逻辑,移除Android不支持的本地地址参数:
    // 原代码
    // m_controller.reset(QLowEnergyController::createCentral(QBluetoothAddress(macAddress), QBluetoothLocalDevice().address()));
    // 修改为
    m_controller.reset(QLowEnergyController::createCentral(QBluetoothAddress(macAddress)));
    
  2. 修正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;
    
  3. 修正异步操作时序,增加通知就绪标记,等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(),等描述符写入完成后再触发数据请求。
  4. 适配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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:30:57