Qt5.15蓝牙开发指南之典型用法
使用 Qt 蓝牙 API 的典型用例是:
检索有关本地蓝牙设备的信息。
扫描范围内的其他蓝牙设备并检索有关它们的信息。
使用 OBEX 对象推送配置文件 (OPP) 将文件推送到远程设备
使用串行端口配置文件 (SPP) 通过 RFCOMM 通道连接到远程设备。
创建一个允许使用 SPP 的传入连接的 RFCOMM 服务器。
检索有关低功耗蓝牙设备的规范。
连接到低功耗蓝牙设备。
从低功耗蓝牙设备接收广告。
请注意,Android 和 Windows 不支持对象推送配置文件。
注意:部分 RFCOMM 功能不能由 Qt 在 Windows 上配置。服务的ServiceClassIds和ProtocolDescriptorList是自动填充的。因此,使用这些字段的自定义值注册服务可能不会在 Windows 上产生预期的结果。
注意: Win32 后端不支持接收信号强度指示器 (RSSI) 以及蓝牙 LE 设备宣传的制造商特定数据。此外,只能找到之前已通过 Windows 设置配对的设备。
检索本地设备信息
Qt 蓝牙 API 有三个主要用途。第一个是获取本地和远程设备信息。检索设备信息的第一步是检查设备上的蓝牙是否可用,并读取本地设备地址和名称。QBluetoothLocalDevice是提供所有这些信息的类。此外,您可以使用它来打开/关闭蓝牙、设置设备的可见性并确定当前连接。
QBluetoothLocalDevice localDevice;QString localDeviceName;// Check if Bluetooth is available on this deviceif (localDevice.isValid()) {
// Turn Bluetooth on
localDevice.powerOn();
// Read local device name
localDeviceName = localDevice.name();
// Make it visible to others
localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable);
// Get connected devices
QList<QBluetoothAddress> remotes;
remotes = localDevice.connectedDevices();}
扫描蓝牙设备
与QBluetoothLocalDevice类似,API 提供QBluetoothDeviceInfo,它为远程设备提供类似的信息。尽管您可以自己创建QBluetoothDeviceInfo对象并用数据填充它们,但更简单的方法是使用QBluetoothDeviceDiscoveryAgent开始自动搜索可连接范围内的可见蓝牙设备。
void MyClass::startDeviceDiscovery(){
// Create a discovery agent and connect to its signals
QBluetoothDeviceDiscoveryAgent *discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
connect(discoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
this, SLOT(deviceDiscovered(QBluetoothDeviceInfo)));
// Start a discovery
discoveryAgent->start();
//...}// In your local slot, read information about the found devicesvoid MyClass::deviceDiscovered(const QBluetoothDeviceInfo &device){
qDebug() << "Found new device:" << device.name() << '(' << device.address().toString() << ')';}
将文件推送到远程设备
找到所需设备后,Qt 蓝牙提供了两个主要用例。更简单的一种是通过 Obex 对象推送配置文件 (OPP) 发送文件。顾名思义,此配置文件可以将文件从一台设备推送到另一台设备。目前无法拉取文件或浏览远程文件系统。该配置文件不需要在交换数据之前将两个设备配对。要将文件推送到远程设备,请创建一个QBluetoothTransferRequest并要求QBluetoothTransferManager通过调用其put()函数来推送包含在请求中的文件。
// Create a transfer managerQBluetoothTransferManager *transferManager = new QBluetoothTransferManager(this);// Create the transfer request and file to be sentQBluetoothAddress remoteAddress("00:11:22:33:44:55:66");QBluetoothTransferRequest request(remoteAddress);QFile *file = new QFile("testfile.txt");// Ask the transfer manager to send itQBluetoothTransferReply *reply = transferManager->put(request, file);if (reply->error() == QBluetoothTransferReply::NoError) {
// Connect to the reply's signals to be informed about the status and do cleanups when done
QObject::connect(reply, SIGNAL(finished(QBluetoothTransferReply*)),
this, SLOT(transferFinished(QBluetoothTransferReply*)));
QObject::connect(reply, SIGNAL(error(QBluetoothTransferReply::TransferError)),
this, SLOT(error(QBluetoothTransferReply::TransferError)));} else {
qWarning() << "Cannot push testfile.txt:" << reply->errorString();}
在设备之间交换数据
在两个启用蓝牙的设备之间进行通信的更灵活的方法是创建一个虚拟串行端口连接并通过该连接自由交换数据。这可以通过串行端口配置文件 (SPP) 来完成。串行端口配置文件模拟通过蓝牙传输协议 RFCOMM 的串行连接。
为了能够接收传入的 SPP 连接,您需要使用QBluetoothServer监听传入的连接。
rfcommServer = new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this);connect(rfcommServer, &QBluetoothServer::newConnection,
this, QOverload<>::of(&ChatServer::clientConnected));bool result = rfcommServer->listen(localAdapter);if (!result) {
qWarning() << "Cannot bind chat server to" << localAdapter.toString();
return;}
使用QBluetoothSocket从扮演客户端角色的另一台设备连接到此服务器:
void ChatClient::startClient(const QBluetoothServiceInfo &remoteService){
if (socket)
return;
// Connect to service
socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
qDebug() << "Create socket";
socket->connectToService(remoteService);
qDebug() << "ConnectToService done";
connect(socket, &QBluetoothSocket::readyRead, this, &ChatClient::readSocket);
connect(socket, &QBluetoothSocket::connected, this, QOverload<>::of(&ChatClient::connected));
connect(socket, &QBluetoothSocket::disconnected, this, &ChatClient::disconnected);
connect(socket, QOverload<QBluetoothSocket::SocketError>::of(&QBluetoothSocket::error),
this, &ChatClient::onSocketErrorOccurred);}
使用这种连接允许双向交换任何形式的数据。它非常适合游戏或在两个设备上的应用程序的两个实例之间同步状态。