当前位置: 首页 > news >正文

Android蓝牙基础框架使用详解

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

研究了一段时间的蓝牙使用,发现网上相关的资料比较贫乏,不像其他 Android 相关资料那么齐全,基本上大部分资料都是在蓝牙联盟SIG 提供的官网

https://www.bluetooth.com/zh-cn/specifications

上查找得到,也没有一个比较稳定好用的基础操作框架,开发时遇到的各种问题也是非常头疼。在此种情况下该框架应运而生,框架中包含了蓝牙设备的基础操作功能,调用简单,已通过实际项目进行验证,并且配有一个比较好用的 demo 演示,下文主要讲述该框架的使用方式。如果对于 Android BLE 还不是很了解,可以先看看我的这篇博文 Android BLE 学习笔记,里面对于蓝牙的基础知识有详细的讲述。

BLE

Android BLE 基础操作框架,基于回调,操作简单。其中包含扫描、连接、广播包解析、服务读写及通知等功能。

  • 项目地址:https://github.com/xiaoyaoyou1212/BLE

  • 项目引入:compile 'com.vise.xiaoyaoyou:baseble:1.0.5'

设备扫描

  • 使用简介

扫描包含三种方式,第一种方式是直接扫描所有设备,可以设置循环扫描,也可以设置超时时间,扫描到的设备可以添加到 BluetoothLeDeviceStore 中统一进行处理,使用方式如下:

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

第二种方式是扫描指定 Mac 地址的设备,一般需设置超时时间,扫描到指定设备后就停止扫描,使用方式如下:

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

第三种方式是扫描指定广播名的设备,同第二种方式类似,也需设置超时时间,扫描到指定设备后也会停止扫描,使用方式如下:

092433_P3Os_1771562.gif

其中扫描到的设备信息都统一放到 BluetoothLeDevice 中,其中包含了设备的所有信息,以下会详细讲解具体包含哪些信息。

  • 示例图

092433_BeeO_1771562.gif

设备连接

  • 使用简介

连接与扫描一样也有三种方式,第一种方式是在扫描获取设备信息 BluetoothLeDevice 后才可使用,可设置连接超时时间,默认超时时间为10秒,使用方式如下:

第二种方式是连接指定 Mac 地址的设备,该方式使用前不需要进行扫描,该方式直接将扫描和连接放到一起,在扫描到指定设备后自动进行连接,使用方式如下:

第三种方式是连接指定名称的设备,该方式与第二种方式类似,使用方式如下:

092433_rRoL_1771562.gif

连接成功后就可以进行相关处理,回调已在底层做了线程切换处理,可以直接操作视图。如果知道该设备服务的UUID,可直接调用 ViseBluetooth.getInstance().withUUIDString(serviceUUID, characteristicUUID, descriptorUUID); ,那么在下面操作设备时就不需要传特征 (BluetoothGattCharacteristic) 和描述 (BluetoothGattDescriptor) 相关参数,如果在连接成功后一直没设置 UUID,那么在操作时则需要传该参数,该内容在下文的设备操作中会详细讲解,此处就不一一讲解了。

  • 示例图

 

092433_vWaG_1771562.gif

设备详情

  • 使用简介

DEVICE INFO (设备信息)

  • 获取设备名称(Device Name): bluetoothLeDevice.getName();

  • 获取设备地址(Device Address): bluetoothLeDevice.getAddress();

  • 获取设备类别(Device Class): bluetoothLeDevice.getBluetoothDeviceClassName();

  • 获取主要设备类别(Major Class): bluetoothLeDevice.getBluetoothDeviceMajorClassName();

  • 获取服务类别(Service Class): bluetoothLeDevice.getBluetoothDeviceKnownSupportedServices();

  • 获取配对状态(Bonding State): bluetoothLeDevice.getBluetoothDeviceBondState();

RSSI INFO (信号信息)

  • 获取第一次信号时间戳(First Timestamp): bluetoothLeDevice.getFirstTimestamp();

  • 获取第一次信号强度(First RSSI): bluetoothLeDevice.getFirstRssi();

  • 获取最后一次信号时间戳(Last Timestamp): bluetoothLeDevice.getTimestamp();

  • 获取最后一次信号强度(Last RSSI): bluetoothLeDevice.getRssi();

  • 获取平均信号强度(Running Average RSSI): bluetoothLeDevice.getRunningAverageRssi();

SCAN RECORD INFO(广播信息)

根据扫描到的广播包 AdRecordStore 获取某个广播数据单元 AdRecord 的类型编号 record.getType(),再根据编号获取广播数据单元的类型描述 record.getHumanReadableType() 以及该广播数据单元的长度及数据内容,最后通过 AdRecordUtil.getRecordDataAsString(record) 将数据内容转换成具体字符串。

  • 示例图

092433_zyYs_1771562.gif

设备操作

  • 使用简介

在操作设备前首先要保证设备已连接成功,那么在设备连接成功获取到 BluetoothGatt 后直接对服务的特征值 UUID 进行相关处理,其中特征值 UUID 有可读、可写、可通知、指示器四种,获取过程如下所示:

092433_tr5R_1771562.gif

在获取到 BluetoothGattCharacteristic 后可进行如下操作: 

设置通知服务

092433_gwsf_1771562.gif

其中最后一个参数是设置该通知是否是指示器方式,指示器方式为有应答的通知方式,在传输时更为靠谱。如果在连接成功时已经知道该设备可通知的 UUID 并且已经设置成功,那么此处还可以如下设置:

读取信息

同上,如果已设置过可读的 UUID,那么此处也可以通过如下方式读取信息:

写入数据

092433_EPk0_1771562.gif

同样,如果在连接成功时设置过可写 UUID,那么此处也可以通过如下方式写入数据:

092433_Qk23_1771562.gif

此处的数据 new byte[]{0x00,0x01,0x02} 为模拟数据,在使用时替换为真实数据即可,切记每次发送的数据必须在20个字节内,如果大于20字节可采用分包机制进行处理。

  • 示例图

640?wx_fmt=png&wxfrom=5&wx_lazy=1

总结

从以上的描述中可以知道,设备相关的所有操作都统一交给 ViseBluetooth 进行处理,并且该类是单例模式,全局只有一个,管理很方便。使用前必须要在 Application 中调用 ViseBluetooth.getInstance().init(this); 进行初始化,在连接设备成功时会自动获得一个 BluetoothGatt,在断开连接时会将该 BluetoothGatt 关闭,上层不用关心连接数最大为6的限制问题,只需要在需要释放资源时调用 ViseBluetooth.getInstance().clear(); 就行,简单易用,这也正是该项目的宗旨。

转载于:https://my.oschina.net/JiangTun/blog/918975

相关文章:

  • JDBC的异常
  • Hibernate(十六):Hibernate二级缓存
  • 函数计算-触发OSS来处理图片加水印和大小裁剪
  • 【Android Studio探索之路系列】之六:Android Studio加入依赖
  • 重装系统再也不用担心桌面文件丢失了
  • Node.js转化GBK编码 - iconv-lite
  • 初学makefile
  • SSM框架搭架
  • Maven工程配置代码覆盖工具Jacoco
  • linux进程D状态_转
  • MongoDB 聚合查询
  • Android组件 - 收藏集 - 掘金
  • java统计abacbacdadbc中的每个字母出现的次数,输出格式是:a(4)b(3)c(3)d(2)
  • ASP.NET Core 简单实现七牛图片上传(FormData 和 Base64)
  • docker 镜像(四)
  • JavaScript-如何实现克隆(clone)函数
  • (三)从jvm层面了解线程的启动和停止
  • 【剑指offer】让抽象问题具体化
  • Android 控件背景颜色处理
  • css布局,左右固定中间自适应实现
  • css系列之关于字体的事
  • gitlab-ci配置详解(一)
  • Java Agent 学习笔记
  • javascript数组去重/查找/插入/删除
  • JS专题之继承
  • leetcode386. Lexicographical Numbers
  • python docx文档转html页面
  • spring boot下thymeleaf全局静态变量配置
  • spring security oauth2 password授权模式
  • Web标准制定过程
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 多线程事务回滚
  • 构建二叉树进行数值数组的去重及优化
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • #QT(TCP网络编程-服务端)
  • #stm32整理(一)flash读写
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (1)Nginx简介和安装教程
  • (arch)linux 转换文件编码格式
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (附源码)计算机毕业设计大学生兼职系统
  • (十六)一篇文章学会Java的常用API
  • (十三)Flask之特殊装饰器详解
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (转)setTimeout 和 setInterval 的区别
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .NET MVC 验证码
  • .net开发时的诡异问题,button的onclick事件无效
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • // an array of int
  • ::before和::after 常见的用法
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • [Angular 基础] - 数据绑定(databinding)