Context

定位水壶架App的iOS端已经完成了80%,在考完矩阵之前,只要把android端的网络和蓝牙交互做完,就可以没什么太大的压力咯.

然而,在搞android端的时候,还是遇到了很多很多问题的.

第一坑

几天前,当我把iOS端蓝牙配对的代码,翻译为Java版本之后,本来想,肯定会轻轻松松,正正常常的运行了.

但是,在连接上定位器之后,总是会卡在搜索服务或者写入xxx这个阶段,然后就断线了.

当时,我觉得,可能是一些小问题,可能是我写漏了什么东西,所以就卡住了.

也怀疑过是Google的亲儿子Nexus蓝牙硬件不给力~

然后就痛苦的去复习了几天矩阵理论…………

但是,就在两个小时之前,我一步一步调试的时候,发现了一个奇怪的现象.

public void onServicesDiscovered(BluetoothGatt gatt, int status);

BluetoothGattCallback中,搜索到service的时候,竟然没有我们自己的service!

所以for循环就那么做完了……什么service都没有找到,最后就被关闭连接了.

这时候,我开始怀疑人生了

难道说,这蓝牙是为iOS设计的!?

赶紧整了一个锤子过来测测.发现锤子是可以找到所有的service的……

难道说,这蓝牙不是为Google设计的!?

这时候,我突然想到了一个问题.和之前几天的实验,可能有点儿关系.

很久很久的几天前

添哥找我说,蓝牙可以设置一个加密密钥,这样子传输数据,就是加密的了.(虽然说,蓝牙和WiFi一样,是要连接之后才能通信的,但是,无线嘛,肯定是要被窃听的)

于是我们就试验了一下,但是蓝牙加密之后,需要手动在手机上点击配对按钮,才可以进行加密通信.

由于android端,这个配对不是特别的明显,不像iOS那么粗暴地弹出来.所以我们最后没有使用这个方案.

这里还可以顺便说说加密

小时候,以为加密的意思就是,给数据加了一把锁.只要用密码把锁打开了,就可以访问数据了.(真单纯)

原来,加密是把数据都给翻译了一遍.即使知道加密解密的算法,使用错误的密钥,可以得到数据,但是这数据,肯定是错的.

当蓝牙加密通信的时候,会分配一个密钥.咱们配对蓝牙鼠标,蓝牙键盘的时候,也常常看到,需要输入个什么pin码,才能配对.一旦这配对了,之后通信就是加密的了.

(假设蓝牙键盘不用配对,不加密通信……)那就是无线的按键记录器啊!

总而言之

这搜索不出我们需要的service就是这个配对的,当我进入系统蓝牙设置,把这个设备的配对给取消了之后,就正常了~.~

第二坑的Context

BLE的GATT的Characteristic有权限控制.

大概就是Read,Write,WriteWithoutResponse,Notify这四种常见权限.

他们用一个8位的flag来控制.因为不是重点,所以懒得讲了.

第二坑

在我解决了Service Discover的问题了之后,我觉得,这下一定可以顺利地跑下去了!

结果卡在了一个写入之后的读取上…

本来,在写入一个数据之后,需要去读取一个反馈的.但是不知道为什么,没有去读取这个数据.

仔细阅读Monitor里面的log.可以发现,之前的读取,都会调用系统的readCharacteristic()函数,而这一次的读取却没有读取,这是为啥子嘞?

权限!

我们有一个Characteristic在写入之后,需要读取反馈.所以需要Read的权限.

然而,在这个Characteristic没有Read的权限的情况下,iOS端竟然还是可以正确的读取到数据!

而Android直接忽略的readCharacteristic()这个函数调用……

虽然说,这硬件是我们自己设计的,讲道理的话,在连接设备之后,并不需要去检查各种权限的.(除非这个硬件是被山寨的)

但是,加上一个权限验证的话,或许可以提高一些软件的稳健性呢?说不定可以让这个系统可以在遇到山寨货的情况下,可以继续正常的工作下去呢~

End

2016马上要结束了,每年都能更加深入的了解一些蓝牙,真的是好刺激!