Android BLE设备蓝牙通信框架BluetoothKit-程序员宅基地

技术标签: 程序员  android  

一、统一解决Android蓝牙通信过程中的兼容性问题

二、提供尽可能简单易用的接口,屏蔽蓝牙通信中的技术细节,只开放连接,读写,通知等语义。

三、实现串行化任务队列,统一处理蓝牙通信中的失败以及超时,支持可配置的容错处理

四、统一管理连接句柄,避免句柄泄露

五、方便监控各设备连接状态,比如手机可同时连接的设备数有限,可以检测设备连接活跃度,在尽可能维持连接的情况下,将最不活跃的设备自动断开。

六、支持多进程APP架构下蓝牙连接的管理

七、支持拦截所有对蓝牙原生接口的调用

对于刚接触Android蓝牙开发的初学者来说,会经常遇到一些奇怪的坑,我也是一路走过来的,将我遇到的一些坑总结了一下,这些坑在这个项目中都修复了,所以大家不必再费时费力去重复踩一遍。这个项目目前正在不断更新,有什么更好的建议大家可以随时提出来。

蓝牙扫描相关的坑


一、startDiscovery在大多数手机上是可以同时发现经典蓝牙和Ble的,但是startDiscovery的回调无法返回Ble的广播,所以无法通过广播识别设备,且startDiscovery扫描Ble的效率比StartLeScan低很多。所以在实际应用中,还是StartDiscovery和StartLeScan分开扫,前者扫经典蓝牙,后者扫低功耗蓝牙。

二、startLeScan() 的时候,在onLeScan() 中不能做耗时操作,特别是周围的BLE设备多的时候,容易导致底层堵塞。如果有耗时操作请丢到子线程中去处理。

三、有的手机会过滤设备广播,一次扫描过程中只发一次request,如果没有收到response就再也收不到该设备广播回调了,解决的办法是多扫几次。

蓝牙连接相关的坑


一、对蓝牙设备的操作不能并行,只能串行,即每次都要在收到上一个操作的回调后才能继续下一个操作。但是断开连接例外,断开连接要马上closeGatt,不用等任务队列中的其他操作了。而且要给所有正在执行或者准备执行的任务都cancel。

二、有时候蓝牙协议栈出现异常可能收不到回调,所以我们要对每个操作做超时检查,否则后面的所有操作都被阻塞了。

三、对于超时的任务,最好closeGatt,下次重新连接的时候重开一个gatt。

四、蓝牙连接可能不稳定,最好支持失败自动重试机制,尤其是连接和发现服务,因为80%的问题都发生在建立连接和发现服务的时候,而且这一块也是最耗时的。

五、当连接建立后,可以由设备端发起更改连接间隔,这样能加快后续发现服务以及数据读写的速度。有的手机discover service很慢,原因是connect interval太大了,有的手机会主动向设备发起更改connect interval,而有的手机却不会。这样的话connect interval相差就会很大,实践中发现有的手机是7ms,有的手机是默认的50ms,所以发现service都要8s,甚至20s的都很寻常,这对用户来说是无法忍受的。所以比较好的办法是设备主动发起更改connect interval

六、同一个设备的所有操作最好都放在同一个线程串行执行,最好不要放在UI线程,虽然这些操作都是异步的,理论上来说不会耗时,但是由于涉及到跨进程,还是有可能出现ANR。另外不建议每个设备都开一个线程,设备多了会费内存也会降低性能。较好的做法是开一个线程,所有设备的操作都在该线程中发起,虽然占用同一个线程,但是每个设备各自维护自己的任务队列。

七、蓝牙操作都是异步的,回调通常都在binder线程里执行,因为这是跨进程回调回来的。一定要注意到这一点,否则会出现一些奇怪的问题。比如writeCharacter在工作线程,但是onCharacterWrite是在binder线程,回调里如果涉及到任务队列的调度一定要post回工作线程中处理,否则会出现多线程造成的数据不一致问题。

八、接着第七条,在回调中post回工作线程处理时要注意不要带句柄,而是要带数据。比如对于onCharacteristicWrite,不要带BluetoothGattCharacteristic,而是要带其中的value。否则会漏掉一些数据,且最后可能收到一组重复的数据。同样的问题在notify上也有。

九、当设备固件升级后,profile可能发生了变化,然而下次discover service的时候还是返回的旧的缓存,这样读写character可能会失败。解决办法是固件升级后,下次连接时刷新一下该设备的缓存。当然,重启蓝牙也会刷新缓存,不过会影响到所有设备。另外有时候discoverService服务发现的不全,或者根本发现不了服务,也可以考虑清除一下缓存。

十、有的手机上discoverService可能会回调不止一次onServiceDiscover,这个要注意防御。

十一、service不要缓存,虽然uuid什么的可能都没变,但是这些service都会和gatt关联的,如果gatt变了,那service就报废了,对这些service和character做任何读写操作都会出错。所以建议每次连接上时都去discover service,不要缓存。

十二、固件升级通常是写设备,为加快写速度,可以在write character时指定no response标志,实践发现速度可以提升2~3倍。不过要注意的是即便带了no response标志,也不代表这种写操作是没有回调的,我们仍然要遵循收到上一次写回调后才能进行下一次写操作。提升写速度的手段还有更改MTU和更改连接间隔,不过更改MTU硬件不一定支持,得尝试几次。

十三、写的时候不要指定writeType,不指定writeType不代表writeType就是WRITE_TYPE_DEFAULT,事实上系统会自动根据property来决定writeType,如果带PROPERTY_WRITE_NO_RESPONSE属性,则会自动选择WRITE_TYPE_NO_RESPONSE,否则才会选择WRITE_TYPE_DEFAULT。

十四、打开/关闭character的notify,必须等收到onDescriptorWrite回调之后才算结束,才能开始下一个任务。

十五、设备的gatt在不用时要及时关闭,系统支持的连接句柄数是有限的,当达到上限后无法再建立新的连接了。

十六、当连接断开后要调closeGatt释放资源,不用调disconnect,也不要下次复用之前的gatt来reconnect,因为有的手机上重连可能会存在问题,比如重连后死活发现不了service。这种情况下,最好只要断开连接就close gatt,下次连接时打开全新的gatt,这样就可以发现service了。

使用


使用起来非常简单,添加一行依赖,然后创建一个全局单例BluetoothClient,详细接口调用方法参考上面的链接。

1、在build.gradle中添加依赖

compile 'com.inuker.bluetooth:library:1.3.8'

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

文末

好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,可以来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。

这里放上一部分我工作以来以及参与过的大大小小的面试收集总结出来的相关的几十套腾讯、头条、阿里、美团等公司21年的面试专题,其中把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分免费分享给大家,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家~

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【延伸Android必备知识点】

这里只是整理出来的部分面试题,后续会持续更新,希望通过这些高级面试题能够降低面试Android岗位的门槛,让更多的Android工程师理解Android系统,掌握Android系统。喜欢的话麻烦点击一个喜欢在关注一下~

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

,让更多的Android工程师理解Android系统,掌握Android系统。喜欢的话麻烦点击一个喜欢在关注一下~

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/2401_84149530/article/details/137720328

智能推荐

前端开发之vue-grid-layout的使用和实例-程序员宅基地

文章浏览阅读1.1w次,点赞7次,收藏34次。vue-grid-layout的使用、实例、遇到的问题和解决方案_vue-grid-layout

Power Apps-上传附件控件_powerapps点击按钮上传附件-程序员宅基地

文章浏览阅读218次。然后连接一个数据源,就会在下面自动产生一个添加附件的组件。把这个控件复制粘贴到页面里,就可以单独使用来上传了。插入一个“编辑”窗体。_powerapps点击按钮上传附件

C++ 面向对象(Object-Oriented)的特征 & 构造函数& 析构函数_"object(cnofd[\"ofdrender\"])十条"-程序员宅基地

文章浏览阅读264次。(1) Abstraction (抽象)(2) Polymorphism (多态)(3) Inheritance (继承)(4) Encapsulation (封装)_"object(cnofd[\"ofdrender\"])十条"

修改node_modules源码,并保存,使用patch-package打补丁,git提交代码后,所有人可以用到修改后的_修改 node_modules-程序员宅基地

文章浏览阅读133次。删除node_modules,重新npm install看是否成功。在 package.json 文件中的 scripts 中加入。修改你的第三方库的bug等。然后目录会多出一个目录文件。_修改 node_modules

【】kali--password:su的 Authentication failure问题,&sudo passwd root输入密码时Sorry, try again._password: su: authentication failure-程序员宅基地

文章浏览阅读883次。【代码】【】kali--password:su的 Authentication failure问题,&sudo passwd root输入密码时Sorry, try again._password: su: authentication failure

整理5个优秀的微信小程序开源项目_微信小程序开源模板-程序员宅基地

文章浏览阅读1w次,点赞13次,收藏97次。整理5个优秀的微信小程序开源项目。收集了微信小程序开发过程中会使用到的资料、问题以及第三方组件库。_微信小程序开源模板

随便推点

Centos7最简搭建NFS服务器_centos7 搭建nfs server-程序员宅基地

文章浏览阅读128次。Centos7最简搭建NFS服务器_centos7 搭建nfs server

Springboot整合Mybatis-Plus使用总结(mybatis 坑补充)_mybaitis-plus ruledataobjectattributemapper' and '-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏3次。前言mybatis在持久层框架中还是比较火的,一般项目都是基于ssm。虽然mybatis可以直接在xml中通过SQL语句操作数据库,很是灵活。但正其操作都要通过SQL语句进行,就必须写大量的xml文件,很是麻烦。mybatis-plus就很好的解决了这个问题。..._mybaitis-plus ruledataobjectattributemapper' and 'com.picc.rule.management.d

EECE 1080C / Programming for ECESummer 2022 Laboratory 4: Global Functions Practice_eece1080c-程序员宅基地

文章浏览阅读325次。EECE 1080C / Programming for ECESummer 2022Laboratory 4: Global Functions PracticePlagiarism will not be tolerated:Topics covered:function creation and call statements (emphasis on global functions)Objective:To practice program development b_eece1080c

洛谷p4777 【模板】扩展中国剩余定理-程序员宅基地

文章浏览阅读53次。被同机房早就1年前就学过的东西我现在才学,wtcl。设要求的数为\(x\)。设当前处理到第\(k\)个同余式,设\(M = LCM ^ {k - 1} _ {i - 1}\) ,前\(k - 1\)个的通解就是\(x + i * M\)。那么其实第\(k\)个来说,其实就是求一个\(y\)使得\(x + y * M ≡ a_k(mod b_k)\)转化一下就是\(y * M ...

android 退出应用没有走ondestory方法,[Android基础论]为何Activity退出之后,系统没有调用onDestroy方法?...-程序员宅基地

文章浏览阅读1.3k次。首先,问题是如何出现的?晚上复查代码,发现一个activity没有调用自己的ondestroy方法我表示非常的费解,于是我检查了下代码。发现再finish代码之后接了如下代码finish();System.exit(0);//这就是罪魁祸首为什么这样写会出现问题System.exit(0);////看一下函数的原型public static void exit (int code)//Added ..._android 手动杀死app,activity不执行ondestroy

SylixOS快问快答_select函数 导致堆栈溢出 sylixos-程序员宅基地

文章浏览阅读894次。Q: SylixOS 版权是什么形式, 是否分为<开发版税>和<运行时版税>.A: SylixOS 是开源并免费的操作系统, 支持 BSD/GPL 协议(GPL 版本暂未确定). 没有任何的运行时版税. 您可以用她来做任何 您喜欢做的项目. 也可以修改 SylixOS 的源代码, 不需要支付任何费用. 当然笔者希望您可以将使用 SylixOS 开发的项目 (不需要开源)或对 SylixOS 源码的修改及时告知笔者.需要指出: SylixOS 本身仅是笔者用来提升自己水平而开发的_select函数 导致堆栈溢出 sylixos

推荐文章

热门文章

相关标签