Android低功耗蓝牙(BLE)开发的一点感受
最近一段时间,因为产品的需要我做了一个基于低功耗蓝牙设备的Android应用,其中碰到了一些困难,使我深深体会到Android开发的难处:不同品牌,不同型号和不同版本之间的差异使得Android应用适配成为一个痛点,尤其是跟硬件相关的,每个厂商在实现Android API的时候,或多或少都会有些差别。这些区别,有些是明显的Bug,有些则是对API理解的差异造成的。
我的开发是基于Android 4.3+ 标准BLE API。Android 4.3之前厂商自己实现的API不在讨论之列。Android 5.0对BLE API进行了改进,但由于基于Android 5.0的智能设备还没有普及,所以我也没有针对Android 5.0进行适配。希望新的API实现可以不仅仅是语义上的统一,在这背后的行为上也应该是一致的,
在这里我分享一些在Android BLE开发过程中遇到的奇怪的事,希望后来者不要走我走过的弯路......
命令执行的顺序
机型 - 红米 1S, Android 4.4.2 / 华为 荣耀6, Android 4.4.2
在BLE设备连接并且做完Service Discovery之后,下一步要做的就是读写设备的Characteristic了,通常在连接后需要读写几个Characteristic。因为我之前做过苹果的开发,这些对BLE读写的命令都是异步,可以并发的,底层实现应该会有一个queue来缓存硬件没有实际执行的命令。于是我想当然的就按照以前的做法实现了对Characteristic的读写,并且在红米 1S上成功运行。可是当我用华为手机测试的时候出错了,我要的数据没有读出来。Debug后发现底层报错,在执行第二个命令时,出现了“有命令在执行中”的错误。请教了伟大的Stack Overflow后才知道,原来有些Android的实现是没有底层的Command Queue的。我在应用层实现了一个简单的Queue,只有当前一个BLE命令执行完成后才进行下一个命令的执行,华为手机的问题就解决了!当然在已经实现了Command Queue的手机上,新的方法也是没有问题的。
所以,同样是实现了Android API,不同的厂商对这背后行为的理解是不同的。如果Google能够不仅对API的语义进行规范,同时也对其行为进行统一,那该多完美!
设备的搜索(Scan)
机型 - Samsung S3 Android 4.3 (机锋ROM)
Android提供了两个API做BLE设备的搜索,一个是带Service UUID过滤,一个不带过滤。我最初的实现选择了带UUID过滤的API,这样效率应该会稍稍高一些吧。在红米1S,华为荣耀6以及魅族MX2上都工作正常,可以搜索到我指定的设备。然而三星S3却无法搜索到任何设备,我百思不得其解,只得再次求助Stack Overflow - 原来不是所有的设备都支持带UUID过滤的设备搜索(怎么会这样?)。我只好使用不带UUID过滤的API了,然后在应用层通过设备名称来过滤我想要的结果。这样一切都好了...吧?
红米1S的奇葩行为
机型 - 红米 1S, Android 4.4.2
俗话说拆了东墙补西墙,用来形容Android开发再恰当不过了,好不容易为一款手机做完了改动,结果原来工作正常的机型却又出了问题。上面为三星S3做过的改动就是一个例子:三星倒是OK了,可是原来一切安好的红米1S却收不到从设备发来的Notification了(读写Characteristic正常)。一开始我很抓狂,不知道为什么红米突然就不工作了,Debug底层也没有报错。万般无奈,只好一点点回退,最后终于发现问题出现在Scan设备的API使用上:如果我用不带UUID过滤的API,红米1S就无法收到从设备发来的Notification!多么奇葩的行为!在红米上我可以搜寻到设备,可以连接,可以发现Service,可以读写Characteristic,却单单无法收到Notification。当我改成带Service UUID过滤的API后,一切就都好了!好吧,这个Bug一般人真的很难理解了,就交给小米去解决吧。
可是我该怎么办呢?只有hack一下,判断机型和版本号,使用不同的BLE Scan API了。太丑陋了!
三星的连接问题
机型 - Samsung Note 2, Android 4.3
三星手机是我做适配时出问题最多的机型了,可能的原因是三星在很早之前就支持了低功耗蓝牙,并且在Android 4.3之前提供了它自己的BLE API。当Android 4.3标准BLE API出来之后,三星做了API的适配,但并不完美。由于条件所限,我们只测试了三星比较老的一些机型,感觉问题还是比较多的,最新的机型以及ROM版本应该会好很多(我们还没有收到关于S5的问题报告)。除了上面讲到的BLE Scan的问题,三星手机对BLE设备的连接也有比较特别的要求:(来自Stack Overflow)某些三星手机在进行BLE连接时,需要在UI thread里调用相应的API。我的应用场景是当手机搜索到设备后自动进行设备连接,在实际的使用中我发现即使是把connect device调用放在UI Thread里,三星手机也是经常不工作的。最后,我在连接设备之前加了一个延时,它就工作了。。。至于是怎么发现的就不啰嗦了,说多了都是泪啊。
Android的BLE API
安卓对于BLE的支持相比iOS来说确实差了许多:API是基于传统Bluetooth API改进的,不支持BLE peripheral模式,在一些API的行为上没有iOS友好,等等。Android 5.0对BLE API进行了重构,并且支持了BLE peripheral模式,希望会大大改善BLE在安卓系统上的体验。
最后贴一段代码,这是用来设置接收设备Notification的,如果不调用writeDescriptor那段代码,notification就不工作。可是谷歌你就不能把它封装在setCharacteristicNotification里么?这个坑不知道害了多少码农啊。。。
- /**
- * Enables or disables notification on a give characteristic.
- *
- * @param characteristic Characteristic to act on.
- * @param enabled If true, enable notification. False otherwise.
- */
- public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
- boolean enabled) {
- if (mBluetoothAdapter == null || mBluetoothGatt == null) {
- Log.w(TAG, "BluetoothAdapter not initialized");
- return false;
- }
- mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
- if (enabled && CHARACT_UUID_BATT_LEVEL.equals(characteristic.getUuid().toString()))
- {
- Log.i(TAG, "setCharacteristicNotification");
- BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
- UUID.fromString());
- descriptor.setValue("00002902-0000-1000-8000-00805f9b34fb");
- mBluetoothGatt.writeDescriptor(descriptor);
- }
- return true;
- }
Android低功耗蓝牙(BLE)开发的一点感受的更多相关文章
- Android 低功耗蓝牙BLE 开发注意事项
基本概念和问题 1.蓝牙设计范式? 当手机通过扫描低功耗蓝牙设备并连接上后,手机与蓝牙设备构成了客户端-服务端架构.手机通过连接蓝牙设备,可以读取蓝牙设备上的信息.手机就是客户端,蓝牙设备是服务端. ...
- 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体解释
转载请注明来源: http://blog.csdn.net/kjunchen/article/details/50909410 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体 ...
- 【转】Android低功耗蓝牙应用开发获取的服务UUID
原文网址:http://blog.csdn.net/zhangjs0322/article/details/39048939 Android低功耗蓝牙应用程序开始时获取到的蓝牙血压计所有服务的UUID ...
- Android低功耗蓝牙(蓝牙4.0)——BLE开发(上)
段时间,公司项目用到了手机APP和蓝牙设备的通讯开发,这里也正好对低功耗蓝牙(蓝牙4.0及以后标准)的开发,做一个总结. 蓝牙技术联盟在2010年6月30号公布了蓝牙4.0标准,4.0标准在蓝牙3.0 ...
- Android蓝牙BLE开发,扫描、连接、发送和读取信息;
1.BLE开发权限 Android蓝牙BLE开发须打开蓝牙权限和6.0位置权限: <uses-permission android:name="android.permission.B ...
- Android低功耗蓝牙(BLE)使用详解
代码地址如下:http://www.demodashi.com/demo/13390.html 与普通蓝牙相比,低功耗蓝牙显著降低了能量消耗,允许Android应用程序与具有更严格电源要求的BLE设备 ...
- 低功耗蓝牙BLE外围模式(peripheral)-使用BLE作为服务端
低功耗蓝牙BLE外围模式(peripheral)-使用BLE作为服务端 Android对外模模式(peripheral)的支持 从Android5.0开始才支持 关键术语和概念 以下是关键BLE术语和 ...
- 深入浅出低功耗蓝牙(BLE)协议栈
深入浅出低功耗蓝牙(BLE)协议栈 BLE协议栈为什么要分层?怎么理解蓝牙"连接"?如果蓝牙协议只有ATT没有GATT会发生什么? 协议栈框架 一般而言,我们把某个协议的实现代码称 ...
- 深入浅出讲解低功耗蓝牙(BLE)协议栈
详解BLE连接建立过程https://www.cnblogs.com/iini/p/8972635.html 详解BLE 空中包格式—兼BLE Link layer协议解析https://www.cn ...
随机推荐
- 【技术贴】破解Myeclipse10.7
程序用的是http://www.cr173.com/soft/58306.html这个破解程序,是英文版的中文版.使用起来非常爽,看下面 使用期间关掉Myeclipse 期间的第三步,点击激活,此时会 ...
- 力控ADO组件数据源设置
1.mysql的ODBC驱动如何下载及安装 地址:http://dev.mysql.com/downloads/connector/odbc/5.1.html Mysql跟力控ado进行交互 第一步: ...
- 提升你的Java应用性能:改善数据处理
许多应用程序在压力测试阶段或在生产环境中都会遇到性能问题.如果我们看一下性能问题背后的原因,会发现很多是由数据处理不当造成.数据处理在应用面对大数据量时是非常关键的.这里有一些实用的数据处理技巧可以帮 ...
- (转载)mysql分屏显示结果
(转载)http://blog.csdn.net/wylkeke/article/details/7280645 linux机器: 在mysql命令行输入pager more就可以分屏显示结果了,取消 ...
- (转载)Linux上iptables防火墙的基本应用教程
(转载)http://www.vpser.net/security/linux-iptables.html iptables是Linux上常用的防火墙软件,下面vps侦探给大家说一下iptables的 ...
- SQL重复记录处理(查找,过滤,删除)
SQL重复记录处理(查找,过滤,删除) ID int Title nvarchar(50) AddDate datetime 数据 www.2cto.com ID ...
- 员工部门表综合查询SQL
--数据库的表设计如下: --部门:部门编号,部门名称,地址: --员工:员工编号,员工名字,职务,管理编号,入职日期,薪资,奖金,部门编号: --创建部门表: CREATE TABLE dept( ...
- AppStore IAP 客户端校验代码
-(BOOL)putStringToItunes:(SKPaymentTransaction*)transaction { NSData * iapData = transaction.transac ...
- YII 表单验证规则
官方文档:http://www.yiichina.com/guide/form.model 类参考手册:http://www.yiichina.com/api/CValidatorhttp://www ...
- linux安装apache软件的过程
参考官方安装指导:http://httpd.apache.org/docs/2.4/install.html 1.下载依赖包 apr/apr-util/pcre 2.解压依赖包 3.安装apr 进入安 ...