最近一段时间,因为产品的需要我做了一个基于低功耗蓝牙设备的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里么?这个坑不知道害了多少码农啊。。。

  1. /**
  2. * Enables or disables notification on a give characteristic.
  3. *
  4. * @param characteristic Characteristic to act on.
  5. * @param enabled If true, enable notification.  False otherwise.
  6. */
  7. public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
  8. boolean enabled) {
  9. if (mBluetoothAdapter == null || mBluetoothGatt == null) {
  10. Log.w(TAG, "BluetoothAdapter not initialized");
  11. return false;
  12. }
  13. mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
  14. if (enabled && CHARACT_UUID_BATT_LEVEL.equals(characteristic.getUuid().toString()))
  15. {
  16. Log.i(TAG, "setCharacteristicNotification");
  17. BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
  18. UUID.fromString());
  19. descriptor.setValue("00002902-0000-1000-8000-00805f9b34fb");
  20. mBluetoothGatt.writeDescriptor(descriptor);
  21. }
  22. return true;
  23. }

Android低功耗蓝牙(BLE)开发的一点感受的更多相关文章

  1. Android 低功耗蓝牙BLE 开发注意事项

    基本概念和问题 1.蓝牙设计范式? 当手机通过扫描低功耗蓝牙设备并连接上后,手机与蓝牙设备构成了客户端-服务端架构.手机通过连接蓝牙设备,可以读取蓝牙设备上的信息.手机就是客户端,蓝牙设备是服务端. ...

  2. 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体解释

    转载请注明来源: http://blog.csdn.net/kjunchen/article/details/50909410 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体 ...

  3. 【转】Android低功耗蓝牙应用开发获取的服务UUID

    原文网址:http://blog.csdn.net/zhangjs0322/article/details/39048939 Android低功耗蓝牙应用程序开始时获取到的蓝牙血压计所有服务的UUID ...

  4. Android低功耗蓝牙(蓝牙4.0)——BLE开发(上)

    段时间,公司项目用到了手机APP和蓝牙设备的通讯开发,这里也正好对低功耗蓝牙(蓝牙4.0及以后标准)的开发,做一个总结. 蓝牙技术联盟在2010年6月30号公布了蓝牙4.0标准,4.0标准在蓝牙3.0 ...

  5. Android蓝牙BLE开发,扫描、连接、发送和读取信息;

    1.BLE开发权限 Android蓝牙BLE开发须打开蓝牙权限和6.0位置权限: <uses-permission android:name="android.permission.B ...

  6. Android低功耗蓝牙(BLE)使用详解

    代码地址如下:http://www.demodashi.com/demo/13390.html 与普通蓝牙相比,低功耗蓝牙显著降低了能量消耗,允许Android应用程序与具有更严格电源要求的BLE设备 ...

  7. 低功耗蓝牙BLE外围模式(peripheral)-使用BLE作为服务端

    低功耗蓝牙BLE外围模式(peripheral)-使用BLE作为服务端 Android对外模模式(peripheral)的支持 从Android5.0开始才支持 关键术语和概念 以下是关键BLE术语和 ...

  8. 深入浅出低功耗蓝牙(BLE)协议栈

    深入浅出低功耗蓝牙(BLE)协议栈 BLE协议栈为什么要分层?怎么理解蓝牙"连接"?如果蓝牙协议只有ATT没有GATT会发生什么? 协议栈框架 一般而言,我们把某个协议的实现代码称 ...

  9. 深入浅出讲解低功耗蓝牙(BLE)协议栈

    详解BLE连接建立过程https://www.cnblogs.com/iini/p/8972635.html 详解BLE 空中包格式—兼BLE Link layer协议解析https://www.cn ...

随机推荐

  1. 【技术贴】破解Myeclipse10.7

    程序用的是http://www.cr173.com/soft/58306.html这个破解程序,是英文版的中文版.使用起来非常爽,看下面 使用期间关掉Myeclipse 期间的第三步,点击激活,此时会 ...

  2. 力控ADO组件数据源设置

    1.mysql的ODBC驱动如何下载及安装 地址:http://dev.mysql.com/downloads/connector/odbc/5.1.html Mysql跟力控ado进行交互 第一步: ...

  3. 提升你的Java应用性能:改善数据处理

    许多应用程序在压力测试阶段或在生产环境中都会遇到性能问题.如果我们看一下性能问题背后的原因,会发现很多是由数据处理不当造成.数据处理在应用面对大数据量时是非常关键的.这里有一些实用的数据处理技巧可以帮 ...

  4. (转载)mysql分屏显示结果

    (转载)http://blog.csdn.net/wylkeke/article/details/7280645 linux机器: 在mysql命令行输入pager more就可以分屏显示结果了,取消 ...

  5. (转载)Linux上iptables防火墙的基本应用教程

    (转载)http://www.vpser.net/security/linux-iptables.html iptables是Linux上常用的防火墙软件,下面vps侦探给大家说一下iptables的 ...

  6. SQL重复记录处理(查找,过滤,删除)

    SQL重复记录处理(查找,过滤,删除)     ID int    Title nvarchar(50)    AddDate datetime    数据  www.2cto.com     ID ...

  7. 员工部门表综合查询SQL

    --数据库的表设计如下: --部门:部门编号,部门名称,地址: --员工:员工编号,员工名字,职务,管理编号,入职日期,薪资,奖金,部门编号: --创建部门表: CREATE TABLE dept( ...

  8. AppStore IAP 客户端校验代码

    -(BOOL)putStringToItunes:(SKPaymentTransaction*)transaction { NSData * iapData = transaction.transac ...

  9. YII 表单验证规则

    官方文档:http://www.yiichina.com/guide/form.model 类参考手册:http://www.yiichina.com/api/CValidatorhttp://www ...

  10. linux安装apache软件的过程

    参考官方安装指导:http://httpd.apache.org/docs/2.4/install.html 1.下载依赖包 apr/apr-util/pcre 2.解压依赖包 3.安装apr 进入安 ...