了解蓝牙

经典蓝牙和低功耗蓝牙差异

经典蓝牙(Bluetooth Classic):分为基本速率/增强数据速率(BR/EDR), 79个信道,在2.4GHz的(ISM)频段。支持点对点设备通信,主要用于实现无线音频流传输,已成为无线扬声器、耳机和车载娱乐系统背后的标准无线电协议。经典蓝牙还支持数据传输程序,包括移动打印。

低功耗蓝牙(Bluetooth Low Energy):为低功耗操作而设计的。工作在2.4GHz无授权ISM频段,共40个信道传输数据。蓝牙LE支持多种通信拓扑,点对点,广播,Mesh。使蓝牙能够支持创建可靠的、大规模的网络。LE也被广泛用于设备定位技术,满足高精度室内定位服务的需求。

经典蓝牙和低功耗蓝牙差异 - 知乎

蓝牙的配对和连接的建立过程

taodudu.cc/news/show-3161112.html?action=onClick

Qt蓝牙模块

支持的平台

Qt 5.14 adds a native Win32 port supporting Classic Bluetooth on Windows 7 or newer, and Bluetooth LE on Windows 8 or newer. It must be enabled at build time by configuration option -native-win32-bluetooth. The UWP backend is used by default if this option is not set and the Win32 target platform supports the required UWP APIs (minimal requirement is Windows 10 version 1507, with slightly improved service discovery since Windows 10 version 1607).

使用

环境

版本:Qt15.15.2

语言:c++

平台:Android 11

蓝牙类型:经典蓝牙(Bluetooth Classic)

代码和说明

使用前在pro文件加载蓝牙模块

QT += bluetooth

大家都有使用蓝牙的经历,一般步骤是:检查蓝牙状态(是否打开)->查找附近的设备->配对->连接->数据的传输,下面就按照这个流程介绍代码。

  • 检查蓝牙状态(是否打开)

QBluetoothLocalDevice提供了获取和设置本地蓝牙设备状态的功能。

可通过

QBluetoothLocalDevice::HostMode QBluetoothLocalDevice::hostMode() const

来获取当前主机的模式,这里只判断是否是未打开,若未打开,可用powerOn() 打开蓝牙,不过调用后,立马再调用创建连接会失败,可能硬件还没准备好。

   QBluetoothLocalDevice* m_pLocalDev;m_pLocalDev = new QBluetoothLocalDevice(this);//检查蓝牙是否未打开if(m_pLocalDev->hostMode()==QBluetoothLocalDevice::HostPoweredOff){m_pLocalDev->powerOn(); //打开蓝牙emit errorBTDevPowerOff();return false;}
  •  查找附近的蓝牙设备

QBluetoothDeviceDiscoveryAgent 类可发现附近的蓝牙设备

void BluetoothDevice::BluetoothDevice()
{...//初始化QBluetoothDeviceDiscoveryAgent* m_pDevDiscoveryAgent;m_pDevDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);connect(m_pDevDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered,     this, &BluetoothDevice::onDeviceDiscovered);connect(m_pDevDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothDevice::onDiscoverFinished);connect(m_pDevDiscoveryAgent, QOverload<QBluetoothDeviceDiscoveryAgent::Error>::of(&QBluetoothDeviceDiscoveryAgent::error),this, &BluetoothDevice::onDiscoverFinished);...
}void BluetoothDevice::refreshBTDevices()
{...//开始查找附近蓝牙设备,根据需求这里限定为经典蓝牙m_pDevDiscoveryAgent->start(QBluetoothDeviceDiscoveryAgent::ClassicMethod);}//查找到的蓝牙设备的信息
void BluetoothDevice::onDeviceDiscovered(const QBluetoothDeviceInfo &device)
{//MAC地址const QString& macAddr = device.address().toString();//设备名称const QString& name= device.name();//判读检测到设备是否与本地设备配对bool isPaired = false;if (pairingStatus == QBluetoothLocalDevice::Paired || pairingStatus == QBluetoothLocalDevice::AuthorizedPaired )isPaired =true;}
//查找结束
void BluetoothDevice::onDiscoverFinished()
{emit discoveryFinished();
}

上方确实获取一些附近的蓝牙设备,但是经常获取不全。情况是这样的:我的手机可查找到待开发设备(后续称设备)的蓝牙,但是设备没有查找到手机蓝牙,所以然后我用手机主动发起配对,是可以成功配对的,后续可以收发文件或者信息。在配对成功后,设备是可以看到我手机的名称和蓝牙MAC地址的,但是QBluetoothDeviceDiscoveryAgent 类仍无法查找到我的手机。

设备可查找到,Qt不行,所以尝试使用Java的方法,直接获取配对设备列表,这个方法是可以的:

package org.qtproject.toolkit.bluetooth;import android.bluetooth.*;import java.util.ArrayList;
import java.util.Set;
import java.lang.String;public class BluetoothInfo
{public BluetoothInfo(){}public  String[] getBondedDevices(boolean isBLE){BluetoothAdapter BTAdapter = BluetoothAdapter.getDefaultAdapter();Set<BluetoothDevice> bondedDevice = BTAdapter.getBondedDevices();ArrayList<String> list = new ArrayList<String>();for (BluetoothDevice bt : bondedDevice){int deviceType = bt.getType();if (!isBLE && (deviceType == BluetoothDevice.DEVICE_TYPE_CLASSIC || deviceType == BluetoothDevice.DEVICE_TYPE_DUAL))list.add(bt.getAddress() + " " + bt.getName());else if (isBLE && (deviceType == BluetoothDevice.DEVICE_TYPE_LE || deviceType == BluetoothDevice.DEVICE_TYPE_DUAL))list.add(bt.getAddress() + " " + bt.getName());}String[] result = (String[]) list.toArray(new String[list.size()]);return result;}
};

c++中调用

#ifdef Q_OS_ANDROID
void BluetoothDevice::getBondedTarget()
{QAndroidJniEnvironment env;QtAndroid::PermissionResult r = QtAndroid::checkPermission("android.permission.ACCESS_FINE_LOCATION");if(r == QtAndroid::PermissionResult::Denied){QtAndroid::requestPermissionsSync(QStringList() << "android.permission.ACCESS_FINE_LOCATION");r = QtAndroid::checkPermission("android.permission.ACCESS_FINE_LOCATION");if(r == QtAndroid::PermissionResult::Denied){qDebug() << "failed to request";}}qDebug() << "has permission";QAndroidJniObject javaClass("org.qtproject.toolkit.bluetooth/BluetoothInfo");QAndroidJniObject array = javaClass.callObjectMethod("getBondedDevices", "(Z)[Ljava/lang/String;", false);int arraylen = env->GetArrayLength(array.object<jarray>());qDebug() << "arraylen:" << arraylen ;m_bondedDevices.clear();for(int i = 0; i < arraylen; i++){QString info = QAndroidJniObject::fromLocalRef(env->GetObjectArrayElement(array.object<jobjectArray>(), i)).toString();BTDeviceInfo devInfo;devInfo.macAddr = info.left(info.indexOf(' '));devInfo.name = info.right(info.length() - info.indexOf(' ') - 1);devInfo.isPaired = true;m_bondedDevices.append(devInfo);}}
#endif
  •  配对

上面我们已经获取附近蓝牙设备的配对状态了,配对的话可以手动配对,或者可以试试下面的方法,不过我测试时由于手机蓝牙搜不到,所以是手动配对的,没有尝试代码请求配对。

void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing)

  • 创建连接

Qt封装了蓝牙客户端(QBluetoothSocket)和蓝牙服务端(QBluetoothServer),跟Tcp的使用很像:Socket尝试连接服务器,Server监测连接,双方都可读写。

以客户端的身份QBluetoothSocket,请求连接服务器。服务器就是之前配对好的手机或者别的设备,注意手机端要打开蓝牙服务器QBluetoothServer,不然是不可能连接成功的。

  • 连接服务器

可以看到,需要传入服务器地址、uuid和打开模式。服务器地址 就是配对的蓝牙MAC地址;uuid有很多值,不同的功能uuid不同,可看一下枚举 enum QBluetoothUuid::ServiceClassUuid 了解一下;打开模式就不用说了。

void QBluetoothSocket::connectToService(const QBluetoothAddress &address, const QBluetoothUuid &uuid, QIODevice::OpenMode openMode = ReadWrite)

代码示例

//初始化QBluetoothSocket* m_pSocket;
QByteArray m_buf;
QString m_strServerUUID;
QString m_strMACAddr;m_pSocket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol,this);
m_strServerUUID = QBluetoothUuid(QBluetoothUuid::SerialPort).toString();connect(m_pSocket,&QBluetoothSocket::connected,this,&BluetoothConnection::onConnected);    connect(m_pSocket,&QBluetoothSocket::disconnected,this,&BluetoothConnection::onDisconnect);
connect(m_pSocket,&QBluetoothSocket::readyRead,this,&BluetoothConnection::onReadyRead);
connect(m_pSocket, QOverload<QBluetoothSocket::SocketError>::of(&QBluetoothSocket::error),this, &BluetoothConnection::onErrorOccurred);//连接服务器 (uuid 可传入,可默认)
void BluetoothConnection::connectToSerive(QString strAddr, QString strUuid)
{if(m_pSocket->state() == QBluetoothSocket::ConnectedState){if(strAddr == m_strMACAddr && strUuid == m_strServerUUID){return;}elsedisconnect();}if(strUuid != "")m_strServerUUID = strUuid;m_strMACAddr = strAddr;m_pSocket->connectToService(QBluetoothAddress(strAddr), QBluetoothUuid(m_strServerUUID),QIODevice::ReadWrite);
}
  •  数据传输处理

数据传输处理这部分,代码就不展示了,需求不同,代码不同。

结束语

安卓的蓝牙客户端大概就是这样了。

蓝牙客户端QBluetoothSocket的使用——Qt For Android相关推荐

  1. Qt经典蓝牙系列四(经典蓝牙客户端的设计 纯Qt代码) android/windows10

    Qt for Bluetooth 蓝牙开发系列文章总纲 文章目录 前言 效果动态图 bluetoothClient定义与构造函数 控制本地开关,并扫描蓝牙设备 与服务器端建立socket连接 与Blu ...

  2. Qt on Android 蓝牙通信开发

    版权声明:本文为MULTIBEANS ORG研发跟随文章,未经MLT ORG允许不得转载. 最近做项目,需要开发安卓应用,实现串口的收发,目测CH340G在安卓手机上非常麻烦,而且驱动都是Java版本 ...

  3. strtof linux内核,Qt for Android使用grpc探索

    利用Qt在Android上使用grpc需要*.a的静态库,Windows上编译的lib库以及linux编译出来的.a,经过尝试,均无法链接成功.本文尝试使用NDK来编译Android版本的grpc静态 ...

  4. Qt on Android 核心编程

    Qt on Android 核心编程(最好看的Qt编程书!CSDN博主foruok倾力奉献!) 安晓辉 著   ISBN 978-7-121-24457-5 2015年1月出版 定价:65.00元 4 ...

  5. 金融理财终端、股票软件数据剖析: 20、qt for android(c/c++)

    1.行情数据 通达信.飞狐等桌面行情&炒股软件当天首次登录时,会下载代码表.除权数据.财务数据等,通达信还有相关提示"正在下载....数据".登录完毕通常进入主界面,即报价 ...

  6. android 蓝牙传输图片吗,如何使用蓝牙将Android手机中的照片和视频副本发送到树莓派...

    步骤1:将Raspberry Pi放入蓝牙设备 完成以下步骤我以前的版本将Raspberry Pi转换为可指导完成此步骤的Bluetooth设备. 步骤2:使Raspberry Pi设备成为Bluet ...

  7. QT for android 获取PDA扫码的广播数据

    QT for android 获取PDA扫码的广播数据 前记 笔者接触到的PDA扫码枪,有三种, 一种是蓝牙枪,连接到手机或者电脑上之后,可以直接把扫描到的数据传送到焦点所在的文本框中:另外两种是普通 ...

  8. qt on android 桌面鼠标事件,Qt on Android 不能自动创建Qt套件的问题的解决

    在按照<Qt on Android核心编程>在搭建Qt on Android开发环境的时,虽然完全按书上的做法做了好几遍,但是在Qt Creator配置Android的Qt套件时,看到Qt ...

  9. Qt for Android (Alpha) 发布

    Qt for Android 是一个为了让Android 平台支持Qt开发的项目. 由于Nokia 选择了Windows Phone 7系统,让很多MeeGo和Qt的开发者无所适从,虽然Intel表明 ...

最新文章

  1. 读完这本书,我做了一个APP
  2. 记录一次OOM分析过程
  3. 正则表达式的常用方法和属性
  4. 【Zookeeper】windows环境下zookeeper安装
  5. redistemplate 设置失效时间_袋式除尘器滤袋失效分析
  6. ThinkPHP 3.2.3 简单后台模块开发(一)常用配置
  7. 用Unity实现游戏弹反效果
  8. 8758:2的幂次方表示
  9. @async 默认线程池_Springboot线程池的使用和扩展
  10. 微信小程序自定义组件生命周期
  11. 首次结算和汇总不一致处理方式总结
  12. Bailian2727 还是采药问题【模拟】
  13. 贪心法—LeetCode 452 用最少数量的箭引爆气球
  14. 清华大学李涓子教授:AI系统如何实现认知推理?
  15. 未来世界的幸存者-读书笔记
  16. 从烂漫少女到已为人母:八年青春 梦断互联网
  17. 牛客每日练习----分元宵,送分啦-QAQ,字符串的问题
  18. Rss Feed是什么
  19. CPU拓扑结构中的Die等级是指什么?
  20. 周哲_java软件工程师 简历

热门文章

  1. 3DMAX可编辑多边形常用命令-桥
  2. android提取pdf中文字,使用iTextG從Android上的pdf文件中提取文本
  3. Xcode使用教程详细讲解 1
  4. docker可道云怎么挂载移动硬盘_【手把手教学】教你使用docker优化斐讯N1可道云...
  5. 微信浏览器 、qq浏览器(video) 的特殊之处
  6. 噪声的频谱分析的重要意义_噪声源识别是什么?具备很重要的现实意义
  7. 常用cadence操作
  8. 良心建议,生活中远离这种人
  9. 4k 对齐,你准备好了吗?
  10. 怎么使用计算机教程,电脑系统教程_电脑ssd固态硬盘怎么用