谈谈几个月以来开发android蓝牙4.0 BLE低功耗应用的感受,注明下时间:2012-10-17写的博客,后期更新的也注明了时间的。
android的就蛋痛了,各个厂商的都定制成不一样的,各个系统版本上也有差异,兼容性很难保证,屏幕大小也差别非常大,开发广泛使用的应用在兼容性上就浪费了很多精力,而需要根据各个厂商提供的不同sdk开发的应用就只能适应某一类手机了,不同厂商的基本上都不兼容得重新开发了。
另外iPhone手机的蓝牙是不能够和android手机的蓝牙通信的,而且iPhone除了蓝牙4.0以外其他版本的蓝牙外设需要通过苹果的认证才能使用的,除非大厂商大批量生产否则不可能通过认证的,当然也可以再加一个认证芯片上去解决。所以很多小公司,解决方案的公司做iPhone的应用只能做蓝牙4.0的,android的则没有这个限制。
另外当初就搜索到健康类的应用有人做出产品的 但不是基于蓝牙4.0低功耗的 还是用蓝牙2.1的spp协议来做的,蓝牙2.1或者3.0的耗电是个比较大的问题,一些小外设,需要用纽扣电池的应用就无法真正使用,对一些创意产品如果需要经常换电池或充电对用户体验都会大打折扣,成本也会大大提高。
相对wifi和zigbee无线方案,蓝牙和无线射频模块nRF24l01成本会低很多,wifi的好处是可以比较方便实现远程控制,距离比较远,信号也相对比较稳定。
补充内容:
经过不断努力终于可以让三星的支持BLE了,HTC1X,moto这几个主流蓝牙4.0的android都可以开发了,但估计以后只会先开发三星销量大的了,不同厂商底层差别太大了。
另外ios6.0可以把iPhone手机当从设备了,可以两台iPhone通过蓝牙通信传数据了,有点类似spp协议,但android的蓝牙4.0的没有看到相关的api。
现在LG出的google nexus 4 也支持ble蓝牙4.0了,但目前也没有对应的api和sdk ,小米2也支持BLE 蓝牙4.0了,由于小米的rom是开源的研究起来估计轻松点,只是用户量太小的话就没必要花精力专门搞了。
ble的发展变化比较快,之前收藏的很多网址现在都访问不了了,更新或者作废了
-------------------------------------------------------------------------
补充内容2:
http://processors.wiki.ti.com/index.php/Category:BluetoothLE
这个是TI的wiki上的文章,上面有moto和HTC的例子程序的,但支持不全面,之前的描述是
MotoRAZRAndroidBLEDemo Obsolete. Updated Motorola BLE SDK with new API is not compatible.
HTC1X BLE API - Complete BLE API for HTC1X (European version only!) NEW!
现在有变成下面的了
MotoRAZRAndroidBLEDemo Obsolete. Updated Motorola BLE SDK with new API is not compatible.
HTC1X BLE API - Complete BLE API for HTC1X (European version only!) Obsolete. Updated Android SDK is not 100% compatible.
三星4.0.4可以搜索到ble设备,但连接有问题,需要升级到android4.1.1以后才行
nordic 发布了两个版本的nRF的app在google play上的(心率计和防丢器在一个应用里),一个摩托罗拉的,一个三星gs3的,可以下载了反编译参考下。
请不要问我怎么下载apk、怎么反编译和怎么用这个的,直接下载连接不是nordic的产品不一定能成功,我自己的xt910和gs3手机连接自己公司开发的csr1000做的蓝牙4.0的产品就都没成功过,听说TI的可以直接连接上,但也读不到数据。
但由于他没有混淆,写法还是值得参考的。给出Samsung Galaxy S3 and Samsung Note 2 app的连接地址:
The nRF Utility App is a tool to demonstrate Bluetooth Smart connection to Samsung Galaxy S3. The App enables you to connect to different Bluetooth Smart accessories such as wireless heart rate monitors and proximity tags. This app complements Nordic Semiconductor’s nRF8000 and nRF518 Series Bluetooth® Smart solutions, compatible with Bluetooth v4.0.
Bluetooth® Smart support for:
- Heart rate monitor
- Proximity tag
Note:
Samsung Galaxy S3 and Samsung Note 2 are currently supported handsets.
Miminum Supported Android Version is Jelly Bean
摩托罗拉现在能访问的心率计sdk网址:
http://www.motorola.com/sites/motodev/library/bluetooth_apis.html
------------------------------------------------------------------------------
Open Bluetooth Low Energy API
http://android-btle.github.com/framework/
这个是博通的开源的api 需要root权限才能用的,用户需要像精简版rom增加google maps的add-on那样增加相关文件到手机系统里面后才能用,除了需要root外对用户要求也比较高。
最近发现三星 Galaxy S3 4.1.1底层ble api的问题也很多,蓝牙硬件很不稳定,连接失败后用系统设置里面关闭开启蓝牙都经常会导致手机重启,用代码延迟重启蓝牙几乎都是导致手机重启的,这种情况在连接异常后让人措手无策,需要用各种延时处理来避免异常和手机重启也导致了自动连接延时缓慢也很无奈,无法完全控制底层。摩托罗拉的虽然问题多但用TI的蓝牙硬件倒还稳定些,可以用代码重启蓝牙来解决各种异常,不过代码量和代码复杂度比三星的多了很多。
摩托罗拉的ble sdk支持设备非安全模式,gs3的不支持,非安全模式下无法bond也就无法连接了。
==========================
2013-01-17 补充
最近有不少人找我要代码和开发,这里说明下,ble app的开发需要跟蓝牙工程师配合才能进行的,每个芯片厂商的底层通信可能不一样的,同样芯片不同sdk版本的结果也是不一样的,目前做解决方案比较多的是TI的芯片,我做的是csr的,还有些人用nordic的,或者博通等其他牌子的,ti能用的app换到csr做的设备不一定能用,同样的防丢器可能每个公司做的蓝牙模块都不一样的,最终使用可能只能匹配自己的蓝牙模块的产品。这里说明下本人时间精力有限,同时基于商业竞争的因素,不能免费提供demo代码和技术支持。
2013-02-01 补充
现在开发完成了几个 三星 Galaxy S3 版本(需要升级到android4.1.1版本)的 BLE 应用了(防丢器、心率计、计步器、体重秤、智能手表、智能灯座),正常情况下使用没有问题,但发现三星gs3手机在discoverCharacteristics后会卡住 导致手机假死状态 不能做其他操作,尽管在连接的时候使用异步Service也一样,使用了其他非蓝牙的app也经常出现这种情况,感觉是手机底层系统的问题,完全没有发挥出四核多线程的优势。代码异常自动重启跟xt910一样甚至更频繁。
2013-02-20 补充
三星终于开了一个ble的专栏出来了 不过很快就废弃了 估计问题太多了不敢公布
http://developer.samsung.com/ble
[Samsung BLE SDK] Samsung BLE SDK 2.0 beta
SAMSUNG Developers ble
在百度搜索 蓝牙4.0 开发,安卓 蓝牙4.0 开发,android 蓝牙4.0开发 android ble 等关键字都可以搜索到这篇博客,也有很多人加入QQ群讨论了。
2013-02-25 补充
最近和朋友交流了解到gs3升级到android4.1.2以后api和android4.1.1有些差别,比如断开连接后不会自动连接几次了。另外note2和gs3的底层也有些差别,有些bug不一样,同样很多问题,估计针对gs3开发的在note2上不能很好的运行,这个兼容性就相当让人恼火了,ios的开发就文档容易多了。
2012-03-12补充
今天试了下gs3的用4.0.4的也可以连接收发数据 可以以4.1.1为基准开发兼容其他系统版本使用。
发现TI的很多人会弹出配对提示框,蓝牙那边设置为非安全连接的,这样就没办法做到自动连接了,很多功能都不能实现了。我用CSR的没有遇到过,ios上的不会弹出,ios和android的底层处理方式不一样的。最近发现做ble的人越来越多了,有时间可能再整理一篇具体开发相关的文章出来。
2013-03-27 补充 上传两张三星ble api的图片:
2013-04-10 补充
最近测试发现NFC严重影响ble使用,试了几次了100%有影响,而且重启蓝牙还会导致手机自动重启
android的ble蓝牙受限制太多了不能同时和wifi NFC一起使用,这个要在产品说明里面标注下,不然出问题用户都不知道怎么回事
Bluetooth may conflict with WIFI and NFC.Advised to turn off WIFI and NFC.
======================================================
2013-04-23 补充
数据通信的时候要找到蓝牙设备最终定义的Handle才行,三星和ios的底层封装了Handle层,不用应用程序处理,只要获取到对应Characteristic就可以了,moto的需要获取到指定Handle后才能用。
http://developer.samsung.com/ble
三星公布ble的api了,跟原来的类不同了
要升级系统到4.2才能用,估计很少人升级到4.2,升级到4.2后原来按反编译api开发的估计也用不了了,兼容又是一个蛋痛的事情了
http://www.beareyes.com.cn/html/2013/05/16/news/79112.shtml
在Google I/O开发者年会上,Google宣布未来几个月内其Android操作系统将全面支持Bluetooth Smart Ready和 Bluetooth Smart设备。
采用新版Android系统的移动电话和平板,只要搭载双模蓝牙芯片即属于Bluetooth Smart Ready规格。Bluetooth Smart Ready是蓝牙技术的进阶标准,几乎可与所有支持蓝牙技术的电子产品兼容,包括键盘、耳机,以及超级省电的下一代Bluetooth Smart智能应用配件(Bluetooth Smart appcessory),如FitBit Flex智能腕带及Pebble智能手表等。
If you want your app to initiate device discovery or manipulate Bluetooth settings, you must also declare theBLUETOOTH_ADMIN
permission. Note: If you use the BLUETOOTH_ADMIN
permission, then you must also have theBLUETOOTH
permission.
Declare the Bluetooth permission(s) in your application manifest file. For example:
<uses-permissionandroid:name="android.permission.BLUETOOTH"/>
<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/>
If you want to declare that your app is available to BLE-capable devices only, include the following in your app's manifest:
<uses-featureandroid:name="android.hardware.bluetooth_le"android:required="true"/>
However, if you want to make your app available to devices that don't support BLE, you should still include this element in your app's manifest, but set required="false"
. Then at run-time you can determine BLE availability by using PackageManager.hasSystemFeature()
:
// Use this check to determine whether BLE is supported on the device. Then
// you can selectively disable BLE-related features.
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
Toast.makeText(this, R.string.ble_not_supported,Toast.LENGTH_SHORT).show();
finish();
}