基于QT的安卓手机蓝牙APP开发

摘要:前段时间用QT写了一个串口调试助手,感受还能够。由于QT是跨平台的,一样一套代码能够在windows上面跑,也能够在linux上面跑,也能够在安卓手机上面跑。并且不须要修改任何东西,编译器会自动给你生成好,这就很是的方便。既然能够在手机上面跑,那么我把串口改为蓝牙不就是一个蓝牙APP了吗?说干就干,网上关于QT开发蓝牙的已经有相关的资料了,因而乎就综合各方面资料,整合了一个蓝牙APP。linux

作这个app不须要任何的Java的知识,你只要会QT最基本的C++基础就能够了。关于代码,我会在文章末尾放上连接。只有你手头有蓝牙模块(HC-05)和安卓手机就能够实现蓝牙APP的功能。windows

1、软硬件平台

1.1 硬件平台

一、蓝牙:HC-05,(淘宝上有卖),它的接口就是跟串口同样的,咱们用到了TX,RX,GND,VCC四个引脚。跟下位机或者用CH340G TTL转USB模块接到PC机上。蓝牙工做在串口模式能够经过AT指令调节。具体参考蓝牙配套的说明文档,最主要的就是请将蓝牙设定为从机模式,不然安卓手机搜寻连接不上。markdown

二、安卓手机:我这里测试用了1台安卓手机,一台是华为荣耀V10,安卓版本10。app

1.2 软件平台

本项目Qt版本是5.13.7,系统是windows 10 x64socket

2、软件基本介绍

由于第一次作蓝牙,就作一个很是简单的雏形,实现蓝牙状态检测、蓝牙的开关、蓝牙的扫描和蓝牙配对连接,而且能像串口助手同样完成数据收发。如图,就是本一开始作的最简单的软件界面,本软件基于mainwinodw控件制做,固然你能够选择其余的,更能够本身定义类。函数

![](img-blog.csdnimg.cn/20210323140… =350x700)oop

蓝牙打开后经过扫描,会将蓝牙的MAC地址还有名字显示在List中,双击List列表中的蓝牙,就会进入actived信号链接的槽函数,执行蓝牙的配对链接。创建链接以后,就相似串口同样能够进行数据通讯了。测试

3、 蓝牙开发

3.1 项目文件准备

须要用到蓝牙就须要在.pro文件中引入库,须要在.pro文件中加入这句话:ui

QT += bluetooth
复制代码

若是没有这句话的话,包含蓝牙目录下的头文件,会提示找不到该文件。以后就是要包含一些蓝牙用到的头文件:this

#include <QtBluetooth/qbluetoothglobal.h>
#include <QtBluetooth/qbluetoothlocaldevice.h>
#include <qbluetoothaddress.h>
#include <qbluetoothdevicediscoveryagent.h>
#include <qbluetoothlocaldevice.h>
#include <qbluetoothsocket.h>
复制代码

请在类中声明定义蓝牙相关句柄:

QBluetoothDeviceDiscoveryAgent *discoveryAgent;//用来对周围蓝牙进行搜寻
QBluetoothLocalDevice *localDevice;//对本地设备进行操做,好比进行设备的打开,设备的关闭等等
QBluetoothSocket *socket;//就是用来进行蓝牙配对连接和数据传输的
复制代码

第一个discoveryAgent是用来对周围蓝牙进行搜寻,localDevice是对本地设备进行操做,好比进行设备的打开,设备的关闭等等。socket就是用来进行蓝牙配对连接和数据传输的。这里要用到这三个。

3.2 蓝牙开关和可见性设定

在构造函数中,为localDevice使用new运算符分配内存。

localDevice = new QBluetoothLocalDevice();
复制代码

1) 蓝牙开关

咱们如何来对蓝牙进行打开和关闭呢?我在open按钮和close按钮的槽函数中对蓝牙进行开关操做。localDevice->powerOn();方法调用打开本地的蓝牙设备。在打开蓝牙以前检测手机是否已经打开了蓝牙,若是没打开就打开,若是打开了就提示蓝牙已打开。

void MainWindow::on_pushButton_openBLE_clicked() {
    if( localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff)//开机没有打开蓝牙
    {
        localDevice->powerOn();//调用打开本地的蓝牙设备
        discoveryAgent->start();//开始扫描蓝牙设备
    }
    else
    {
         QMessageBox::information(this, tr("成功"), tr("蓝牙已打开"));
    }
}
复制代码

close按钮的槽函数:

void MainWindow::on_pushButton_closeBLE_clicked() {
    socket->close();
    QMessageBox::information(this, tr("成功"), tr("已断开链接"));
}
复制代码

3.3 蓝牙设备的查找

使用蓝牙设备的查找,就要用到 discoveryAgent 这个类的实例化。咱们须要在构造函数中对discoveryAgent =new QBluetoothDeviceDiscoveryAgent();分配内存。而后就可使用这个类的方法来对蓝牙进行查找了。除此以外,还要进行一个信号和槽的连接。

connect(discoveryAgent,
		SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
		this,
		SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo))
		);
复制代码

在咱们发现设备的时候,这个deviceDiscovered信号被触发,进入到addBlueToothDevicesToList的函数中。在上面的软件界面,咱们的最上面蓝牙列表下的控件是ListIte控件,这里作一个槽函数,将发现的设备打印到这个列表中列出来。

//在ListWidget上显示查找到的蓝牙设备
void MainWindow::addBlueToothDevicesToList(const QBluetoothDeviceInfo &info) {
    QString label = QString("%1 %2").arg(info.address().toString()).arg(info.name());
    QList<QListWidgetItem *> items = ui->listWidget->findItems(label, Qt::MatchExactly);

    if (items.empty())
    {
        QListWidgetItem *item = new QListWidgetItem(label);
        QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(info.address());
        /* 蓝牙状态pairingStatus,Pairing枚举类型 * 0:Unpaired没配对 * 1:Paired配对但没受权 * 2:AuthorizedPaired配对且受权 */
        if (pairingStatus == QBluetoothLocalDevice::Paired || pairingStatus == QBluetoothLocalDevice::AuthorizedPaired )
            item->setTextColor(QColor(Qt::red));
        else
            item->setTextColor(QColor(Qt::black));
        ui->listWidget->addItem(item);
    }
}
复制代码

这里给出这个函数,每一句话十分的好理解,这里增长点选操做,当点击listItem中的项目的时候,背景颜色会翻转,双击这个项目就会和这个蓝牙设备创建链接,这里有个actived槽函数,在这个槽函数里面就会进行蓝牙的连接。

3.4 蓝牙设备的创建链接

在说蓝牙设备链接以前,不得不提一个很是重要的概念,就是蓝牙的Uuid,引用一下百度的:

在蓝牙中,每一个服务和服务属性都惟一地由"全球惟一标识符" (UUID)来校验。正如它的名字所暗示的,每个这样的标识符都要在时空上保证惟一。UUID类可表现为短整形(16或32位)和长整形(128位)UUID。他提供了分别利用String和16位或32位数值来建立类的构造函数,提供了一个能够比较两个UUID(若是两个都是128位)的方法,还有一个能够转换一个UUID为一个字符串的方法。UUID实例是不可改变的(immutable),只有被UUID标示的服务能够被发现。

在Linux下你用一个命令uuidgen -t能够生成一个UUID值;在Windows下则执行命令uuidgen 。UUID看起来就像以下的这个形式:2d266186-01fb-47c2-8d9f-10b8ec891363。当使用生成的UUID去建立一个UUID对象,你能够去掉连字符。

在咱们的项目中,用到的模式是串口模式,咱们须要创建一个存储Uuid的机制,以下:

static const QLatin1String serviceUuid("00001101-0000-1000-8000-00805F9B34FB");
复制代码

这个字符串里面的内容就是串口模式的Uuid,若是你开发的蓝牙也是要使用串口,你直接Copy过去就能够了,若是你使用其余模式,本身去找这个Uuid码是多少。

在使用蓝牙创建链接,须要创建蓝牙socket服务。请在构造函数中增长对socket的分配内存,要注意的是构造函数中的参数须要给定模式。

socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
复制代码

   在Qt文档中,给了3中模式,具体如何这里不作引伸,读者须要请本身查询文档。但RfcommProtocol,属于模拟RS232模式,我就叫串口模式了。当双击ItemList控件中的项目时候,会进入到actived槽函数和蓝牙进行连接,那么如何链接呢?在itemList中会打印一个蓝牙的MAC地址信息,咱们会将这个Mac地址保存在QBluetoothAddress这个类的实例化中,并将这个address传递给socket,做为连接依据。

//蓝牙链接
void MainWindow::connectBLE(QListWidgetItem *item) {
    QString text = item->text();
    int index = text.indexOf(' ');
    if (index == -1)
        return;
    QBluetoothAddress address(text.left(index));
    QString name(text.mid(index + 1));
    QMessageBox::information(this,tr("提示"),tr("设备正在链接中..."));
    socket->connectToService(address, QBluetoothUuid(serviceUuid) ,QIODevice::ReadWrite);
}
复制代码

咱们经过对字符串的处理,将获得address信息。经过socket->connectToService(....),把地址,Uuid,和蓝牙模式传递进去,当执行完这句话的时候,安卓手机开始和你选择的蓝牙设备进行连接。

一样在socket中也提供了丰富的槽函数,好比成功创建链接信号,成功断开信号,这里在槽函数中能够作一些例子,这里给出例子:

//蓝牙链接设备成功后会中止搜索设备,显示链接成功
connect(socket,SIGNAL(connected()),this,SLOT(connectOK()));
//蓝牙连断开链接后,会显示已断开链接
connect(socket,SIGNAL(disconnected()),this,SLOT(connectNot()));
//接受到上位机传来的数据后显示,会触发接受数据函数
connect(socket,SIGNAL(readyRead()),this,SLOT(readBluetoothDataEvent()));
//链接成功
void MainWindow::connectOK() {
    discoveryAgent->stop();  //中止搜索设备
    QMessageBox::information(this, tr("成功"), tr("链接成功!"));
}
//链接失败
void MainWindow::connectNot() {
    QMessageBox::information(this, tr("提示"), tr("已断开链接"));
}
复制代码

3.5 发送和接收数据

蓝牙发送和接收数据,也是经过socket进行。发送数据十分简单:

void Widget::on_pushButton_send_clicked() {
    QByteArray arrayData;
    QString s("Welcome to pay attention to WeChat public number Guoguo young teachers\n");
    socket->write(s.toUtf8());
}
复制代码

这里经过socket->write函数,完成发送。发送以后,上位机,我用的串口助手会显示该信息。 串口助手接受到信息,那么接收数据呢? 咱们在构造函数中,须要创建这样的一个信号和槽的连接:

connect(socket,
       SIGNAL(readyRead()),
       this,
       SLOT(readBluetoothDataEvent())
       );
复制代码

readyRead()信号触发,跳进readBluetoothDataEvent中。

void Widget::readBluetoothDataEvent() {
    QByteArray line = socket->readAll();
    QString strData = line.toHex();
    comStr.append(strData);
    if(comStr.length() >= 4) 
    {
	    ui->textBrowser_info->append(comStr + "\n");
	    comStr.clear();
    }
}
复制代码

以上就是QT开发一个蓝牙APP的全部步骤了,是否是很简单啊!赶快下载源码试一试吧!

公众号后台回复:蓝牙小车,便可获取下载连接。

基于QT的安卓手机蓝牙APP开发