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);}

使用这种连接允许双向交换任何形式的数据。它非常适合游戏或在两个设备上的应用程序的两个实例之间同步状态。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 最近项目使用蓝牙,之前并没有接触,还是发现了很多坑,查阅了很多资料,说的迷迷糊糊,今天特查看官方文档。 说下遇到的...
    King9527阅读 5,814评论 0 1
  • 一、前言: 普通蓝牙设备官方文档 Android 平台包含蓝牙网络堆栈支持,凭借此支持,设备能以无线方式与其他蓝牙...
    因为我的心阅读 12,822评论 1 9
  • 前言 在众多的消费电子类产品中,蓝牙作为一种简易的通讯方式,因此功耗小、体积小、成本低等优势,被广泛的应用于耳机、...
    心若冰清_阅读 7,192评论 0 10
  • 声明 普通蓝牙设备官方文档 Android 平台包含蓝牙网络堆栈支持,凭借此支持,设备能以无线方式与其他蓝牙设备交...
    bug喵喵阅读 3,821评论 0 0
  • 普通蓝牙设备官方文档 Android 平台包含蓝牙网络堆栈支持,凭借此支持,设备能以无线方式与其他蓝牙设备交换数据...
    sydMobile阅读 69,722评论 5 43