【QT】蓝牙库QtBluetooth实现设备通讯(1)

发布于:2025-06-21 ⋅ 阅读:(19) ⋅ 点赞:(0)

前言

之前有用QT for Android实现对蓝牙键盘的控制,主要使用的是网上找的实例文件,结果没实现效果,卡在UUID上,当时也没有进行深入研究地层和代码,就不了了之了。这回基于上次的情况,对QT的蓝牙库进行深挖,完成对蓝牙的设备的控制。

实验的流程:最初是直接分析QT官方的实例代码,然后去做蓝牙键盘的连接,结果没有成功,蓝牙耳机倒是识别出来了,但是耳机控制交互并不直观,首选还是键盘。因此选择蓝牙模拟设备、蓝牙键盘,和第三方的蓝牙调试助手,去验证在windows平台下功能可用性。然后将蓝牙模拟设备与QT官方实例去进行调试,验证实例的可用性。当知晓实例可用后,结合QT官方文档去分析实例,完成自定义实例的编写。最终,完成对蓝牙库QtBluetooth的初步分析

本博文对以上实验流程中遇到问题进行记录,对编写的实例进行整理。在完成本博文后,后续继续进行蓝牙库QtBluetooth研究,以完成windows平台下,蓝牙键盘与QT实例的设备通讯

工具准备

  • 蓝牙键盘、蓝牙耳机,可以查一下是BLE还是常规的。

  • 蓝牙调试助手找到了mock bluetooth,但是使用效果不理想,从官方下载mock bluetooth完成后,会同步下载手游助手,然后在里面跑这个软件。如果android平台下载可能效果不错,由于博主是windows平台,就没有选择。首选了Serial_Net_Bluetooth,这个使用很方便,可以从如下网盘下载,提取码: 5hfu。

  • 蓝牙模拟设备是在手机上下载了蓝牙调试宝,可以模拟蓝牙服务。

  • QT版本5.11.2,MSVC2025 64bit,QT官方库5.11链接

windows下QT蓝牙搜索依赖系统连接的原因分析

在进行设备连接时候,会发现即使用第三方蓝牙调试助手,依旧无法搜索到蓝牙设备,究其原因,才发现在windows上使用QT的蓝牙搜索功能时,必须先通过系统设置打开蓝牙并连接设备,才能在程序中搜索到设备,这是由windows的蓝牙架构和QT蓝牙模块的实现方式共同决定的

核心原因分析

1.windows蓝牙架构限制

  • 独占访问机制:
    windows系统默认将蓝牙设备的控制权交给第一个连接的应用程序。当系统设置连接了设备后,该设备会被系统标记为“已连接”,并由windows蓝牙服务管理。
  • 权限层级:
    windows优先处理系统级别的蓝牙连接,第三方应用(如QT程序)需要通过系统API访问设备,且权限低于系统服务。

2.QT蓝牙模块的实现方式

  • 依赖底层API:
    QT在windows上的蓝牙功能依赖于windows蓝牙API,而这些API通常只能访问系统已配对或已连接的设备。
  • 扫描范围限制:
    QT的QBluetoothDeviceDiscoveryAgent在windows上实际调用的是windows的扫描接口,而 windows默认仅返回已配对设备或最近连接过的设备。

为什么必须先通过系统连接?

  • 设备缓存机制:
    windows会将已连接的设备信息缓存到系统数据库中,QT程序通过API访问的是这个缓存列表,而非直接扫描物理设备。
  • 权限验证:
    某些设备(如K380蓝牙键盘)需要先通过系统配对,以建立信任关系和获取访问权限。

QT库类分析

在进行QT程序编写时,对类的分析是一个至关重要的事情,有效的分析可以让我们了解类的特点和应用场景,本博文对QT程序编写过程中常用的方法进行介绍。

QBluetoothDeviceDiscoveryAgent

该类官方介绍如下,可以了解到该类是支持常规蓝牙和BLE蓝牙的搜索的,在搜索范围上有2个值GeneralUnlimitedInquiryLimitedInquiry,这个值的设置与QBluetoothLocalDevice的设置有关联,在后文介绍会有提及。

  • GeneralUnlimitedInquiry :所有可发现设备,扫描时间长(约20-30秒),耗电高。适用:设备发现、首次配对。
  • LimitedInquiry:有限可发现设备,扫描时间短(约10秒),耗电低。适用:快速重连、省电模式。
    在这里插入图片描述

QBluetoothLocalDevice

该类有4个值,对4个值的区分很有必要,官方的介绍如下:
在这里插入图片描述
对内容进行翻译与梳理,介绍如下:

  • HostPoweredOff:蓝牙已关闭。
  • HostConnectable:蓝牙已开启,仅对之前已配对设备连接。用途:保持与已配对设备的连接;隐私保护:防止被陌生设备发现。
  • HostDiscoverable:蓝牙已开启,对所有可见,Android上最多激活5min,注意超时后自动切换到 HostConnectable。用途:首次配对新设备。
  • HostDiscoverableLimitedInquiry:蓝牙已开启,仅对支持LimitedInquiry模式有限查询的设备可见。用途:快速连接已知设备;比 HostDiscoverable 更省电。

总结内容,从以下几个部分进行总结:
在这里插入图片描述

设备UUID查询

在进行UUID选择以实现对应服务搜寻时,设备UUID的获知是一个至关重要的事情。当然可以采用QT类实现,但在进行蓝牙键盘K380的UUID获取时,发现为空,同时用蓝牙调试工具进行查询依旧如此。因此,可采用以下2个方法进行验证:

方法一:注册表查询

首先,在设备管理器找到蓝牙设备,然后查看属性-详细信息,将属性项选择为设备实例路径,将值进行复制。
在这里插入图片描述
然后进入注册表,去值所在路径进行查询,如上图所示,路径为:

计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\BTHENUM\Dev_F473353E1F73\7&24ced181&0&BluetoothDevice_F473353E1F73\Device Parameters

其中计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum为需要增加的路径。
查看Bluetooth_UniqueID数值为{00000000-0000-0000-0000-000000000000}#F473353E1F73_00000000,明显该值有问题。此处考虑可以增加一行记录,键为ServiceUUIDsDeviceClass,值设置成UUID的值,但是设置重启后发现没有效果,而且设置的记录会清除。因此,可以明确该方法无效。

在这里插入图片描述

方法二:使用PowerShell直接获取UUID

先用指令Get-PnpDevice -Class Bluetooth | Where-Object {$_.FriendlyName -like "Keyboard K380"} | Format-List DeviceID, FriendlyName获取蓝牙键盘设备信息,然后根据输出的DeviceID,代入如下指令Get-PnpDeviceProperty -DeviceID "<DeviceID>" -KeyName "{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\0005",将指令中的DeviceID替换为上面指令输出的信息。运行后,蓝牙键盘K380输出如下。
在这里插入图片描述
换一种指令,直接获取所有蓝牙设备的完整路径Get-PnpDevice -Class Bluetooth | Format-Table DeviceID, FriendlyName,结果如下,发现键盘依旧没有输出UUID。
在这里插入图片描述

ps:以上2个方法,可以验证蓝牙键盘K380设备获取UUID有问题,但是模拟设备、蓝牙耳机获取都正常,因此后续对蓝牙键盘的研究关于这点上要查找原因。

实例创建

在完成了以上的分析与问题总结,对QT官方实例btchart、btscanner进行研究,尤其是btchart可以用于收发通讯。结合官方实例的分析,编写实例需求如下:

  • 可以进行全局和局部设备的搜索选择;
  • 可以进行蓝牙适配器的设置;
  • 支持BLE和常规蓝牙设备;
  • 可以进行收发通讯。

首先打开蓝牙调试宝,将服务端模式开启。其次用QBluetoothLocalDevice完成本地蓝牙适配器的初始化,用QBluetoothDeviceDiscoveryAgent完成蓝牙信号的搜索。UI界面如下:
在这里插入图片描述
点击扫描设备设备可以进行扫描到设备的显示,用QBluetoothDeviceInfocoreConfigurations()方法做好蓝牙设备类型区分,其中0是未知设备;1是BLE设备;2是常规蓝牙设备;3是兼顾BLE和常规蓝牙的设备。选择其中测试的模拟设备REDMI K80->常规进入设备对应服务搜索的UI界面。
在这里插入图片描述
设备对应服务搜索的UI界面,可以展示该设备所有的UUID列表,其中SPP服务的UUID:00001101-0000-1000-8000-00805F9B34FB。当设备UUID中包含该UUID,可以进行SPP通讯收发,与模拟设备进行通讯。
在这里插入图片描述
在信息输入框输入通讯信息,点击Send按钮进行通讯,测试结果如下:
在这里插入图片描述

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到