Android低功耗蓝牙总结

1a ff 4c 00 02 15 fd a5 06 93 a4 e2 4f b1 af cf c6 eb 07 64 78 25 27 11 4c b9 c5

1a 表示接下来的数据有 26 字节

FF 表示数据类型,此处类型是 厂商自定义数据类型(这里的厂商指的是苹果公司,因为 iBeacon 是苹果公司提出的)

4C 00 表示公司的 ID,此处的 004C 代表苹果公司

02 15 Beacon 的标识位,必须是这样的

fd a5 06 93 a4 e2 4f b1 af cf c6 eb 07 64 78 25

表示 Beacon UUID

27 11 是 major 的值

4C b9 是 minor 的值

C5 表示 Measured Power 表示的是此设备在 1 米处的 RSSI 值,用于距离测算

这段内容其实主要是苹果公司在蓝牙协议的基础上定义的。

如果符合 1AFF4C000215 则说明此设备是 iBeacon 设备

蓝牙应答包

04 3e 38 0d 01 1b 00 01 8b 03 00 b0 01 c2 01 00 ff 7f af 00 00 00 00 00 00 00 00 00 1e 29个字节

02 0a 00 08 16 f0 ff 64 27 11 4c b9 11 09 4d 69 6e 69 42 65 61 63 6f 6e 5f 30 30 39 30 37 30个字节

其中第一行与上面一样,这里不再介绍

02 0a 00

02 表示接下来的数据长度 2 个字节

0a 表示数据类型 这里表示 Tx Power Level 取值范围是 -127 到 127 dBm

00 表示 0 dBm

08 16 f0 ff 64 27 11 4c b9

08 表示数据长度

16 表示 Service Data 由 Service UUID 和 service 数据组成 前两个字节是 UUID 后面是数据

f0ff 是 Service UUID

64 27 11 4c b9 是数据

11 09 4d 69 6e 69 42 65 61 63 6f 6e

11 表示数据长度

09 表示设备完整的名字

4d 69 6e 69 42 65 61 63 6f 6e 就是设备名字的 ASSIC 码了 对应 MiniBeacon

M i n i B e a c o n

5f 30 30 39 30 37

这几个数据就是 Beacon 开发者随便乱加入的数据了,不符合协议内容

Android 中接受到的广播包

上面我们分别分析了蓝牙原始数据包中的广播包和应答包,其实对于 iBeacon 来说广播包中的大多数内容其确定的,只有 UUID Major Minor 会有变化。而且每个位置所代表的作用都已经被 苹果公司 定义好了。如果想要 iBeacon 发出的数据包有更多的内容,那么我们就可以在应答包中做文章了,应答包是有 32 个字节的。我们只需要按照协议的内容向应答包中添加数据就可以了。

对于 Android 客户端,通过 Scanresult.getScanRecord().getBytes() 获得的广播包是 62 个字节,它把上面原始数据包中的内容提取出来了,只保留了第二行内容。就是 蓝牙广播包第二行(30 byte) + 蓝牙应答包第二行(最多 32 byte,数目不确定),如果位数不够的话就用 0 补充。

所以我们现在就可以很好根据获得的 byte[] 数组来解析广播包了。

// 现在就获得广播包了

byte[] result = ScanResult.getScanRecord().getBytes();

// UUID 包含 result[9] 和 result[24]

result[9]—result[24];

// Major

result[25] result[26]

// Minor

result[27] result[28]

// Measured Power

result[29]

// 一般我们都是直接会先把 广播包转成 16 进制的格式然后来截取

String uuid = broadcast.substring(18, 50);

// 至于后面应答包的内容就要根据具体的广播包格式来进行解析了,比如你们公司的硬件开发人员把电池电量放入了里面,那么你们就约定好放在什么位置,到时候你直接取就可以了。

关于 ScanResult 中的方法

这几个方法所获得内容都不是直接从 Android 中收到的广播(ScanResult.getScanRecord().getBytes())中解析出来的,而是从原始数据包中解析的。

getTxPower 获取传输功率,如果这个 iBeacon 不支持的话,那么结果就是 127

后面这几个方法作用不大,关键看设备是否支持

关键方法

ScanRecord 中的这几个方法就很重要的,这几个方法都和我们收到的广播包有关系。

比如:如果应答包中对 Tx Power Level 进行了设置我们就可以通过 getTxPowerLevel() 来直接获取。比如上面例子中的广播包,通过调用方法 getTxPowerLevel() 就可以得到 0

其他方法类似,只要你的应答包中数据的格式正确,就可以解析出来。

举例说明:

比如 Android 端收到的广播包是:

0201061AFF4C0002150123456789ABCDEF0123456789ABCDEF00000007C5 广播包

020A00 0303F1FF 0E16F1FF6400000007AC233F66C401 070965526F7574650000 应答包

getTxPowerLevel() 返回 0 因为在应答包中有正确的格式数据 020A00

getServiceData() 也会返回值,因为在应答包中有对应的数据 0E16F1FF6400000007AC233F66C401

0E 表示数据长度

16 表示类型 此处表示 Service Data - 16-bit UUID (不仅仅是 UUID 还带有数据) 前两个字节表示 UUID 后面是数据

F1FF 表示 UUID

6400000007AC233F66C401 表示数据

Map<ParcelUuid, byte[]> getServiceData() 返回的值就是用 UUID 和 数据作为键值对的形式

此处返回的 Map 集合中的内容是 注意:变化的 UUID 其余位数不会变化,如果广播包中 UUID 不是 F1FF,那么只需要对应替换就可以了

ParcelUuid = ParcelUuid.fromString(“0000fff1-0000-1000-8000-00805f9b34fb”);

byte[] 就是数据部分对应的字节数值

List<ParcelUuid> getServiceUuids() 方法对应的就是应答包中的数据 0303F1FF 由于只出现一次,所以 list 的 size就只有一个就是 F1FF 对应的 ParcelUuid 就是 ParcelUuid.fromString("0000fff1-0000-1000-8000-00805f9b34fb");

同样的下面几个方法也是对 Android 端收到的 62 byte 的广播包中数据的解析所得

String getDeviceName() 获得是名字 需要广播包中有对应的数据 070965526F7574650000

SpareArray<byte[]> getManufacturerSpecificaData() 获取的制造商的数据,对应 4C000215

尾声

评论里面有些同学有疑问关于如何学习material design控件,我的建议是去GitHub搜,有很多同行给的例子,这些栗子足够入门。

有朋友说要是动真格的话,需要NDK以及JVM等的知识,首现**NDK并不是神秘的东西,**你跟着官方的步骤走一遍就知道什么回事了,无非就是一些代码格式以及原生/JAVA内存交互,进阶一点的有原生/JAVA线程交互,线程交互确实有点蛋疼,但平常避免用就好了,再说对于初学者来说关心NDK干嘛,据鄙人以前的经历,只在音视频通信和一个嵌入式信号处理(离线)的两个项目中用过,嵌入式信号处理是JAVA->NDK->.SO->MATLAB这样调用的我原来MATLAB的代码,其他的大多就用在游戏上了吧,一般的互联网公司会有人给你公司的SO包的。
至于JVM,该掌握的那部分,相信我,你会掌握的,不该你掌握的,有那些专门研究JVM的人来做,不如省省心有空看看计算机系统,编译原理。

一句话,平常多写多练,这是最基本的程序员的素质,尽量挤时间,读理论基础书籍,JVM不是未来30年唯一的虚拟机,JAVA也不一定再风靡未来30年工业界,其他的系统和语言也会雨后春笋冒出来,但你理论扎实会让你很快理解学会一个语言或者框架,你平常写的多会让你很快熟练的将新学的东西应用到实际中。
初学者,一句话,多练。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 13
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值