Android BLE蓝牙踩坑总结

简介

自从Android-BLE库开源了一段时间以来,越来越多的小伙伴问到了各种各样的关于BLE的奇怪问题,在这里我想跟大家分享一下本人对于Android BLE蓝牙的一些看法和解决方式,避免刚接触的小伙伴再次踩坑。

题外话

很多人曾问过我这个问题,为什么其他手机都没什么问题,就华为的一些手机老是连接不稳定,经常连接的很慢,而且连接上还经常断开。的确,在这里强调一下华为的一部分手机确实很容易出现这种问题,有时候软件、硬件都搞不定,而且经常性收到客户投诉关于华为手机连接稳定性问题,这个的确没有完全解决的办法,只能靠App和硬件的优化,并不是想甩锅给华为,咱也不敢问到底是什么原因,而且我们公司专门针对各个Android版本的手机做过测试,包括蓝牙传输速率的测试,最后发现华为P20的速度竟然跟小米8的速度差了好几倍,按理说P20手机也不便宜啊,为什么手机蓝牙芯片不能做的再好一点呢?

问题集锦

一、扫描问题

1、扫描不到设备
先确定下列几项是否满足:
1、蓝牙是否打开
2、蓝牙相关权限是否授权(6.0以上位置权限)
3、7.0以上手机很多需要手动打开GPS
2、有时候刚开始扫描还正常,过段时间扫描不到设备?
原因:
出现这个问题的很多是Android7.0以上手机,为什么呢?
因为Google为了防止Android7中的BLE扫描滥用,从而做了一些限制,即不要在30s内对蓝牙扫描
重复开启-关闭超过5次。
建议:
设置扫描周期>6s, 用户点击扫描后不要重复进行扫描,可以做一个是否正在扫描的标志位,如果
正在扫描就不做重复扫描动作了。

BLE扫描滥用预防

AOSP-BLE扫描滥用说明

3、为什么有些手机退到后台扫描不到设备
Android8.0以上退到后台息屏后,为了保证省电等原因,如果不设置ScanFilters的话是默认扫不到设备的,
所以解决办法就是设置如下:
            mScannerSetting = new ScanSettings.Builder()
                    //退到后台时设置扫描模式为低功耗
                    .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
                    .build();
            mFilters.add(new ScanFilter.Builder()
                    //过滤扫描蓝牙设备的主服务
                    .setServiceUuid(ParcelUuid.fromString("0000ffff-0000-1000-8000-00805f9bfffb"))
                    .build());
            mScanner.startScan(mFilters, mScannerSetting, mScannerCallback);

息屏状态下,蓝牙扫描日志,因为扫描周期是12s,所以打印的时间戳间隔是12s,这里的日志为系统日志。

image

image
翻译:
启动蓝牙扫描。扫描结果将通过回调传递。对于未经过滤的扫描,扫描是停止在屏幕上关闭,以节省
电力。再次打开屏幕时,将恢复扫描。为了避免这种情况,请使用适当的扫描过滤器进行文件扫描。

二、连接问题

1、为什么同时多个设备连接时经常连接不成功?
可能原因:
在使用 BluetoothDevice.connectGatt() 或者 BluetoothGatt.connect() 等建立 BluetoothGatt
连接的时候,在任何时刻都只能最多一个设备在尝试建立连接。如果同时对多个蓝牙设备发起建立 Gatt
连接请求。如果前面的设备连接失败了,后面的设备请求会被永远阻塞住,不会有任何连接回调。
建议:
如果要对多个设备发起连接请求,最好建立一个请求队列,前一个设备请求建立连接,后面请求在队列中等待
。如果连接成功了,就处理下一个连接请求。如果连接失败了(例如出错,或者连接超时失败),就马上调用
BluetoothGatt.disconnect()/close()来释放建立连接请求,然后处理下一个设备连接请求。
2、为什么有时候连接成功了,但是发现不了服务及特征值,进而影响数据的接收和发送。
连接成功后,会进行BluetoothGatt.discoverServices()去发现服务,进而设置特征值等,因为该方法是在主
线程中执行的,所以为了连接过程的可靠性,建议不要在该过程中,在主线程中不要处理太多的操作(尤其是频
繁绘制操作)。
3、为什么连接成功后,过不一会又断开了?
这个问题其实并不主要是客户端的问题,所以不要一味的在代码中找问题了,建议与硬件沟通,让其进行优化
,如可以调整设备的连接参数(ConnectionInterval(连接间隔)、SlaveLatency(从设备延迟或者从设备时
延)、SupervisionTimeout(超时时间或者监控超时)),这三个参数是低功耗蓝牙中十分重要的连接参数,
一起决定了BLE的功耗,一般硬件设备会在APP连接成功时主动去更新一下这三个参数,以保证不同手机的差异
性得到一致,但是APP端是没办法控制这三个参数的。
4、最大连接数问题
标准答案是7个,为什么是7个,这个我们可以从如下图所示的底层蓝牙源码中找到依据。

https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/include/bt_target.h#1428

stackoverflow问答社区

image

5、连接api的使用问题
发起蓝牙Gatt连接 BluetoothDevice.connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback),这里有一个参数autoConnect,如果为 true
的话,系统就会发起一个后台连接,等到系统发现了一个设备,就会自动连上,通常这个过程是非常慢的。为
false 的话,就会直接连接,通常会比较快。同样,BluetoothGatt.connect()只能发起一个后台连接,不是直
接连接,所以连接时设置autoConnect参数设置为false,如果想实现重连功能的话,自己去手动实现吧,实在不
想手动写,那就用Android-BLE库吧,你想要的基本都有。
6、为什么连接总是报133、19之类的非0异常
原因:可能由于首次连接蓝牙后没有释放掉gatt资源导致的蓝牙协议栈异常,从而出现133或257
19等值不为0:由于协议栈,连接建立失败

建议:在onConnectionStateChange()回调中判断,若state非0(连接断开),调用gatt.close(),手动释放掉
gatt相关资源

三、数据发送问题

1、为什么连接成功了,发送数据总是失败?
原因:
1、首先确定主服务是否正确,再看设置的读、写特征值是否正确

2、因为BLE发现服务和设置特征、通知等是需要耗时的,所以你并不能连接成功后立马发送数据,可以等到在
onDescriptorWrite()回调时,或者手动延迟一段时间再去做发送操作。
2、为什么要分包发送
BLE4.0蓝牙发送数据,单次最大传输20个byte,如果是一般的协议命令,如:开关灯、前进左右等等,是不需要
分包的,如果是需要发送如:图片、BIN文档、音乐等大数据量的文件,则必须进行分包发送,BLE库中已经提
供了发送大数据包的接口,需要的小伙伴可以去下载DEMO查看用法。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • 背景 蓝牙历史说到蓝牙,就不得不说下蓝牙技术联盟(Bluetooth SIG),它负责蓝牙规范制定和推广的国际组织...
    徐正峰阅读 12,188评论 6 33
  • 前言 经过一段时间的蓝牙开发接触,想总结下现实Android ble模块开发的流程以及遇到的问题。 1.初识BLE...
    大地零一阅读 9,305评论 1 11
  • BLE简述 蓝牙是一套非常庞大复杂的协议栈,通俗的说就是一组应用于无线系统通信的约定,各个厂家根据这个约定生产出了...
    dxdingdu阅读 11,293评论 5 37
  • 初识低功耗蓝牙 Android 4.3(API Level 18)开始引入Bluetooth Low Energy...
    JBD阅读 112,396评论 46 342
  • 2019年日更第168天 上篇“借双眼睛看世界”,漫谈碎片化的时代下的学习、思考与自我安顿;中篇“何以遣有涯之生”...
    晰然阅读悦成长阅读 333评论 1 1