Qt on Android 蓝牙通信开发
版权声明:本文为MULTIBEANS ORG研发跟随文章,未经MLT ORG允许不得转载。
最近做项目,需要开发安卓应用,实现串口的收发,目测CH340G在安卓手机上非常麻烦,而且驱动都是Java版本的, 就没选择,博主在大二的时候学习过Java SE基本的语法,写过一些小程序就放弃了Java的道路。最后选择了蓝牙无线透传模块,实现串口通信。现在Qt跨平台支持安卓,是在是令人欣喜。在网上找资料,用Qt on Android做蓝牙驱动的几乎没有,也没有相关例程,所以准备撰写此文,献给广大嵌入式程序员们
2018/6/27更新:
增加Java版本的蓝牙通信,文章地址:https://www.cnblogs.com/sigma0/p/9234478.html
一、软硬件平台
1.1 硬件平台
1. 蓝牙:HC-05,(淘宝上有卖),它的接口就是跟串口一样的,我们用到了TX,RX,GND,VCC四个引脚。跟下位机或者用CH340G TTL转USB模块接到PC机上。蓝牙工作在串口模式可以通过AT指令调节。具体参考蓝牙配套的说明文档,最主要的就是请将蓝牙设定为从机模式,否则安卓手机搜寻链接不上。
2.安卓手机:我这里测试用了2台安卓手机,一台是小米4移动版,安卓版本6.0.1;一台是MOTO MT887,安卓版本4.1.2。
1.2 软件平台
本项目Qt版本是5.7,系统是windows 8.1 x64
二、软件基本介绍
因为第一次做蓝牙,就做一个非常简单的雏形,实现蓝牙状态检测、蓝牙的开关、蓝牙的扫描和蓝牙配对链接,并且能像串口助手一样完成数据收发。如图,就是本一开始做的最简单的软件界面,本软件基于QWidget控件制作,当然你可以选择mainwinodw,更可以自己定义类。
软件界面
我不用介绍每个部位是什么了,都会明白吧?蓝牙打开后通过扫描,会将蓝牙的MAC地址还有名字显示在List中,我们双击List列表中的蓝牙,就会进入actived信号连接的槽函数,执行蓝牙的配对连接。建立连接之后,就类似串口一样可以进行数据通信了。另外,点击send按钮之后会发送一堆字符串。
三、 蓝牙开发
3.1 项目文件准备
需要用到蓝牙就需要在.pro文件中引入库,我没有用Qt quick,用的是纯C++写的代码,你需要在.pro文件中加入这句话:
QT += bluetooth
#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;
3.2 蓝牙开关和可见性设定
localDevice = new QBluetoothLocalDevice();
1) 蓝牙开关
if( localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff ) {ui->pushButton_openBluetooth->setEnabled(true);ui->pushButton_closeDevice->setEnabled(false); }else {ui->pushButton_openBluetooth->setEnabled(false);ui->pushButton_closeDevice->setEnabled(true); }
在构造函数中
那么,我们如何来对蓝牙进行打开和关闭呢?我在open按钮和close按钮的槽函数中对蓝牙进行开关操作。
open按钮的槽函数:
void Widget::on_pushButton_openBluetooth_clicked() {localDevice->powerOn();ui->pushButton_closeDevice->setEnabled(true);ui->pushButton_openBluetooth->setEnabled(false);ui->pushButton_scan->setEnabled(true); }
localDevice->powerOn();方法调用打开本地的蓝牙设备,然后你可以根据自己的喜好完成对按钮的使能和禁止操作。
void Widget::on_pushButton_closeDevice_clicked() {localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff);ui->pushButton_closeDevice->setEnabled(false);ui->pushButton_openBluetooth->setEnabled(true);ui->pushButton_scan->setEnabled(false); }
close设备和我们的open设备的方法在形式上不一样,我还以为他们两个是对称的,但是事实上不是,只能用这样的方法对蓝牙进行关闭。
2) 蓝牙可见性
if( localDevice->hostMode() == QBluetoothLocalDevice::HostDiscoverable ) {ui->checkBox_discoverable->setChecked(true); }else {ui->checkBox_discoverable->setChecked(false); }
我的设计中,蓝牙可见如界面图用的是checkBox空间完成的,通过setChecked()方法,一开机对是否可见进行。
localDevice->setHostMode( QBluetoothLocalDevice::HostDiscoverable);
同理,不可见你也能想到对吧。
3.3 蓝牙设备的查找
connect(discoveryAgent,SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),this,SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo)));
在我们发现设备的时候,这个deviceDiscovered信号被触发,进入到addBlueToothDevicesToList的函数中。在上面的软件界面,我们的最上面蓝牙列表下的控件是ListIte控件,这里做一个槽函数,将发现的设备打印到这个列表中列出来。
void Widget::addBlueToothDevicesToList( const QBluetoothDeviceInfo &info ) {QString label = QString("%1 %2").arg(info.address().toString()).arg(info.name());QList<QListWidgetItem *> items = ui->list->findItems(label, Qt::MatchExactly);if (items.empty()) {QListWidgetItem *item = new QListWidgetItem(label);QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(info.address());if (pairingStatus == QBluetoothLocalDevice::Paired || pairingStatus == QBluetoothLocalDevice::AuthorizedPaired )item->setTextColor(QColor(Qt::green));elseitem->setTextColor(QColor(Qt::black));ui->list->addItem(item);}}
这里给出这个函数,每一句话十分的好理解,这里增加点选操作,当点击listItem中的项目的时候,背景颜色会翻转,双击这个项目就会和这个蓝牙设备建立连接,这里有个actived槽函数,在这个槽函数里面就会进行蓝牙的链接。下一章节写这个如何连接。
3.4 蓝牙设备的建立连接
在Linux下你用一个命令uuidgen -t可以生成一个UUID值;在Windows下则执行命令uuidgen 。UUID看起来就像如下的这个形式:2d266186-01fb-47c2-8d9f-10b8ec891363。当使用生成的UUID去创建一个UUID对象,你可以去掉连字符。
static const QLatin1String serviceUuid("00001101-0000-1000-8000-00805F9B34FB");
socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
void Widget::itemActivated(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));qDebug() << "You has choice the bluetooth address is " << address;qDebug() << "The device is connneting.... ";QMessageBox::information(this,tr("Info"),tr("The device is connecting..."));socket->connectToService(address, QBluetoothUuid(serviceUuid) ,QIODevice::ReadWrite);}
我们通过对字符串的处理,将得到address信息。通过socket->connectToService(....),把地址,Uuid,和蓝牙模式传递进去,当执行完这句话的时候,安卓手机开始和你
选择的蓝牙设备进行链接。
同样在socket中也提供了丰富的槽函数,比如成功建立连接信号,成功断开信号,这里在槽函数中可以做一些例子,这里给出例子:
connect(socket,SIGNAL(connected()),this,SLOT(bluetoothConnectedEvent()));connect(socket,SIGNAL(disconnected()),this,SLOT(bluetoothDisconnectedEvent()));
void Widget::bluetoothConnectedEvent() { // 2017/10/8 更新一下,请在这里插入关闭蓝牙查找服务,否则数据会断。 // 具体语句是什么我忘记了,反正使用discoveryAgent的一个什么close,或者stop的方法qDebug() << "The android device has been connected successfully!";QMessageBox::information(this,tr("Info"),tr("successful connection!")); }void Widget::bluetoothDisconnectedEvent() {qDebug() << "The android device has been disconnected successfully!";QMessageBox::information(this,tr("Info"),tr("successful disconnection!")); }
最后,还有一个断开连接函数。通过断开连接按钮的槽函数实现。
void Widget::on_pushButton_disconnect_clicked() {socket->disconnectFromService();}
3.5 发送和接收数据
void Widget::on_pushButton_send_clicked() {QByteArray arrayData;QString s("Hello Windows!!!\nThis message is sended via bluetooth of android device!\n");arrayData = s.toUtf8();socket->write(arrayData); }
这里通过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);qDebug() <<"rec data is: "<< comStr;qDebug() <<"The comStr length is: " << comStr.length();if(comStr.length() >= 30) {ui->textBrowser_info->append(comStr + "\n");comStr.clear();}}
我这里是这样处理的,当然了,你有你自己的处理方法,意思就是那么个意思。
四、结束语
转载于:https://www.cnblogs.com/sigma0/p/5769527.html
Qt on Android 蓝牙通信开发相关推荐
- Android 蓝牙通信开发
Android 蓝牙通信开发 Receiver的设置 一.Receiver1(蓝牙状态的改变通过广播接收) 二.Receiver2(蓝牙搜索到设备.绑定设备(配对)通过广播接收) 服务端代码 客户端代 ...
- android蓝牙通讯方法,Android蓝牙通信开发教程(详解版)
Android 系统提供蓝牙 API 包 android.bluetooth,允许手机设备通过蓝牙与其他设备进行无线连接. Android 的蓝牙 API 可提供以下功能: 需要说明的是,Androi ...
- Android 蓝牙通信
Android 蓝牙通信 一.现在的无线通信方案及差别 二.蓝牙传输功能开发 1.准备阶段 1)权限 2)蓝牙的开启/关闭/状态 判断设备是支持蓝牙 获取蓝牙状态 启动/关闭 2.查找设备 1) 让设 ...
- Android 蓝牙BLE开发详解
Android 蓝牙BLE开发详解 由于年初接手了个有关蓝牙BLE的项目,开始了对蓝牙ble的学习,经过长时间的慢慢学习(学得太慢,太拖了),终于了解了该怎么写蓝牙BLE,现在就给大家分享一下. 一. ...
- Android蓝牙通信
Android蓝牙串口通讯 闲着无聊玩起了Android蓝牙模块与单片机蓝牙模块的通信,简单思路就是要手机通过蓝牙发送控制指令给单片机,并作简单的控制应用.单片机的蓝牙模块连接与程序暂且略过,此文主要 ...
- android 蓝牙通信编程
http://blog.csdn.net/yudajun/article/details/8362916 公司项目涉及蓝牙通信,所以就简单的学了学,下面是自己参考了一些资料后的总结,希望对大家有帮助. ...
- Android蓝牙BLE开发(一)-基本原理
公司有需求要做蓝牙BLE传输,经查阅后发现关于BLE开发的知识还真不多.对于BLE开发的同学来说,我的建议是先快速了解一下BLE的基本原理,磨刀不误砍柴工. 什么是BLE BLE全称Bluetooth ...
- Android蓝牙BLE开发
最近正在研究Android的蓝牙BLE开发学习,以下是自己做的个人总结 1.1何为BLE? 首先得说明什么是低功耗蓝牙BLE,BLE的全称为Bluetooth low energy(或称Blooth ...
- Android蓝牙通信具体解释
蓝牙通信的大概过程例如以下: 1.首先开启蓝牙 2,搜索可用设备 3,创建蓝牙socket.获取输入输出流 4,读取和写入数据 5.断开连接关闭蓝牙 还要发送配对码发送进行推断! 以下是全部的源码:不 ...
最新文章
- HTTP/FTP压力测试工具siege
- ChannelFactory.Endpoint 上的地址属性为空。ChannelFactory 的终结点必须指定一个有效的地址。...
- 奇异值分解SVD与PCA
- Linux系统VIM编辑器管理(2)
- 【HTTP】POST 与 PUT 方法区别
- Springboot启动完毕后提供了立刻执行自定义程序的两个接口类
- 互联网之“死”:为什么开发者会排斥新技术?
- 2021年qs世界大学计算机科学排名,2015年QS世界大学计算机专业排名
- 神舟笔记本电脑更改启动盘顺序
- BZOJ5336:[TJOI2018]游园会——题解
- NOI 1.11(02)二分法求函数的零点
- Kotlin苦海无涯(四) Object
- 有关H5第六章的背景与阴影介绍
- 10步Navicat for Mysql12.1.20破解激活方法(适用于Navica12.1系列软件)
- 中科蓝讯 AB32VG1 RISC-V开发板模块评测任务大挑战
- 使用beautifulSoup
- Error Domain=NSCocoaErrorDomain Code=3840 The operation couldn’t be completed. (Cocoa error 3840.)
- h5获取浏览器的相机和摄像头权限
- 【Excel自动化办公Part4】:调整字体与样式的操作——字体、边框、对齐格式、颜色填充
- 手推BN、IN、LN、GN
热门文章
- 7个使用JavaScript构建数据可视化的实用工具库,希望你能喜欢
- 2020年我对大前端的认知,前端开发有哪些变化
- 打印服务器协议,基于TCP/IP协议的嵌入式网络打印服务器设计
- matlab repmat_利用MATLAB实现KNN
- springboot中获得app_Spring Boot 应用程序启动流程分析
- 快速排序菜鸟python_python菜鸟教程学习13:文件操作
- 【博客大赛】100行js代码实现网站在线用户数量统计 nodejs + socket.io方案
- 如何用softmax和sigmoid来做多类分类和多标签分类
- JedisPool.getResource()方法卡死的解决办法
- 【论文阅读】Deep Cocktail Network: Multi-source Unsupervised Domain Adaptation with Category Shift