一周前客户提交了一个Bug。 具体的问题是这样的, 客户的一台设备坏了, 临时换了一台设备后发现,新换的设备不像老设备那样每次进行蓝牙连接时都提示要确认配对。这个问题确实是不对比不知道,一直以来谁都没注意这个问题, 以为正常的情况就是每次连接时都需要确实配对。实际上安卓系统上蓝牙首次连接会出现确认配对的对话框, 首次连接配对成功后, 以后再次连接时不需要重新配对, 也不会出现确认配对的对话框除非你从蓝牙设置的配对列表中删除该设备。收到问题后,还是按照一般解决Bug的三部曲: 1.复现问题 2. 分析问题 3. 解决问题进行操做。

复现问题

根据以往的经验, 如果能复现问题,基本上就能解决问题。 首先要求用户把那台有问题的设备寄给我们,收到设备后首先试图复现一下问题。 我们这个设备的使用场景是:我们的APP运行在手机或平板上(为方便区分以下都叫用户端), APP通过蓝牙和设备连接, 连接成功后可以接收设备发送的数据。收到这台设备后, 我们先设计了几个测试用例:

  1. 同一台设备, 不同的用户端
    我们在几台不同的手机/平板上运行APP试图通过蓝牙连接设备, 确实每次连接都弹出确认对话框。
  2. 不同的设备,不同的用户端
    在这个用例中, 我们试了几台手机/平板,几台设备。 每部手机都去连接几台测试的设备, 测试结果发现有一台设备在和某些手机连接时弹出对话框,在和一台荣耀平板连接时不弹出对话框。 还有一部小米手机无论连接哪台设备都不弹出对话框。

通过上面的测试用例, 我们发现了一些现象:

  • 我们测试的大部分设备,无论用户端是什么系统(一部小米手机除外),问题都会出现。
  • 有一台小米手机就对任何设备都不出现问题。
  • 有一台设备, 用一台荣耀平板和上面提到的一台小米手机测量不出现问题, 用其它的平板都会出现问题,而这台荣耀平板连接其它的设备都会出现问题。

分析问题

经过上面的测试, 我们确认了大部分设备确实存在问题。用户端安卓系统对问题的处理方式不一样, 比如一部小米手机连接所有设备都不出问题,但具体问题出在哪里了,从这些现象很难判断, 还需要进一步分析出问题时用户端到底哪不同来决定。为此我们需要从代码的层面和通讯协议的层面分析下正常情况和非正常情况的不同。幸运的是正好上面提到的那台荣耀平板, 连接一台设备没问题, 而连接其他的设备都有问题。 那么我们可以比较连接没问题设备时的通讯协议和连接有问题的设备时的协议不同来定位问题。为此我们首先重新写了一个APP,在这个APP中只做蓝牙连接,其他什么也不做。写这个APP的目的就是简化代码减少多余代码有可能引入的Bug。 这样一来就还剩一个问题: “我们怎么Debug蓝牙通讯协议呢?” 百度一下很快就能得到答案。实际上手机都有一个功能,如下图:

图一 打开蓝牙HCI日志

在手机的设置-->开发人员页面下有一个开启蓝牙HCI信息收集日志选项开关,如图中标红处, 打开该开关,就可以收集本机发送和接收的蓝牙HCI包。看起来很简单是不是, 打开这个开关,我们测试连接一下两台设备, 然后就拿到了蓝牙包日志,分析日志,就可以发现问题了。 可是理论很清晰,现实很残酷啊。我们打开了开关, 分别通过蓝牙连接了上面提到的两台设备, 一台有弹出确认框,一台没有。测试完成了,准备获取日志,可是将PAD连接到电脑,到处也找不到btsnoop_hci.log文件。按照bt_stack_log.conf设置的路径也找不到。真是让人着急。 首先想到的是root一下这个PAD, 但是查了一下华为官网,华为现在已经不再提供root解锁码,大致度娘了一下,root这个平板不太容易,比较简单的方法还是看看有没有别的办法获取的蓝牙日志。度娘了一下,感觉方法都不靠谱,果断翻墙去google。说真心话, 碰到一些比较冷僻复杂的技术问题, 百度上还真难找到线索。不服不行,老外的程序员回答问题的质量还是比较高的。

在这个帖子里,有人提到现在大部分手机厂商不再把蓝牙日志放在用户可以访问的文件分区(难怪我们找不到),取而代之的是可以通过bug report获取。按照帖子里的方法,先执行下面的指令:

adb bugreport c:\tmp\

得到一个压缩文件bugreport-JDN2-W09HN-HUAWEIJDN2-W09HN-2021-06-08-15-07-38.zip,展开这个文件到一个目录后会看到一个同名的TXT文件。然后执行:

btsnooz.py bugreport-JDN2-W09HN-HUAWEIJDN2-W09HN-2021-06-08-15-07-38.txt > btsnoop.log

其中btsnooz.py 是一个Python文件,可以点击上面的链接获取。根据Google的说明, 这个script文件用于从bug report中获取蓝牙日志。终于我们得到了蓝牙日志。总算可以再向前前进一步去分析蓝牙日志了。

蓝牙日志的分析软件比较常用的有三个:

  • Wire Shark
  • Ellisys
  • Frontline Comproble Protocol Analysis System

    在网上找了这三个软件的评测版试了一下, 最后觉得还是Frontline比较好用。主要是这个软件有一个时序图的功能,这个功能对于我们这种对蓝牙协议不是很熟的人来说很有用。

图二 每次需要确认配对的设备蓝牙连接时序图

图三 不需要确认配对的设备蓝牙连接时序图

对比蓝牙授权请求发出后两台设备交互请求的不同, 我们很容易发现, 双方在交互Key的过程中,出现了问题。需要确认设备配对(图二)双方交互key后, 设备方不认可,随后就发出了设备I/O兼容请求。这应该就是问题的所在, 设备蓝牙模块在处理key时应该有bug。

问题解决

至此,我们确定了问题的原因。 那么下来怎么解决这个问题可并不容易。解决这个问题有两个方案:

  1. 蓝牙固件代码修改----这个问题大概率是蓝牙硬件模块代码的问题(当然安卓系统也有可能有问题,这种概率很小,因为一方面大部分设备都出问题,另一方面,市场上蓝牙设备那么多,如果是安卓系统的问题,这个问题应该早被提出来修改了。),涉及到硬件的固件的修改。这个方案是比较优雅的解决方案,但实施起来也有一定难度, 因为我们的设备都已经卖给了客户, 升级固件实际上是很难实现的。不管怎么说,厂家修复后,以后的产品不会出现问题。
  2. 修改应用程序软件代码-------这个方案的思路是,设置消息优先级,在程序中优先接收蓝牙配对请求,模拟系统蓝牙配对的过程,在过程中不显示对话框。请参考这篇文章。
    但这种方法因为需要BLUETOOTH_PRIVILEGED权限,而这个权限是系统级应用才有的,需要对应用进行系统签名,做成系统应用。这对我们并不适合。当然重写蓝牙通讯栈API或者不用安卓系统蓝牙API用第三方的蓝牙API也能解决这个问题,但不太现实, 所以我们只能放弃软件的解决方案。只能选用第一种方案,虽然不够完美,因为现有的用户没法更改固件。 不过幸亏,这个Bug不影响蓝牙传输功能, 对用户来说就是繁琐些,但也只能如此了。

蓝牙连接每次弹出确认框问题的排查及解决相关推荐

  1. ant design vue:upload打开选择文件弹框前弹出确认框

    看antd文档,刚开始我用得beforeUpload来实现,勉强能完成我想要的功能,但是流程上不完美,需要先选择了文件,才能弹出确认框,但是我的确认框其实跟文件没有关系,我想要先弹确认框再打开文件选择 ...

  2. php实现删除功能,点击删除弹出确认框,点确定删除数据,点取消返回。删除了商品后总价要相应的改变

    1.连接数据库: 2. 订单信息从product数据库下computers表调出不分页显示在网页product.php; 实现删除功能,点击删除弹出确认框,点确定删除数据,点取消返回.删除了商品后总价 ...

  3. php删除记录前的判断弹窗,thinkPHP删除前弹出确认框的简单实现方法

    这篇文章主要介绍了thinkPHP删除前弹出确认框的简单实现方法,结合实例形式分析了thinkPHP前台HTML部分结合js控制弹出框效果,以及后台控制器的删除数据处理功能,需要的朋友可以参考下 本文 ...

  4. C#点击关闭按钮 弹出确认框

    0. 引言 C#点击关闭按钮弹出确认框共两种方法实现 一种重写系统的方法,一种更改关闭按钮事件的方法 1. 方法1:重写关闭方法 //重写关闭窗口按钮方法 protected override voi ...

  5. Layui开关添加弹出确认框及layer.confirm的回调

    一.confirm回调 在给开关添加确认框之前,先打印了confirm的几种回调,每次的顺序点击为确认按钮.取消按钮.右上角的X按钮. 第一种 1.写法 2.打印值 第二种 1.写法 2.打印值 可以 ...

  6. 【HTML】网页弹出确认框

    想要在网页中弹出提示框,在用户点击确定 或 取消后执行相应的操作 confirm if(confirm("是否确认?")){ 是===}, {否===}

  7. 复选框弹出确认框,点取消,仍会打钩或者把钩消掉

    首先这个需求当时困扰了我两天!!这两天我尝试了各种事件 不知道你们有没有遇见过这样的情况,就是需要你在复选框的基础上,要实现确认框,(目的:防止误点击,而勾选复选框) 我本身是后端开发,前端只是略懂 ...

  8. android蓝牙配对 自动联接,如何实现android蓝牙开发 自动配对连接,并不弹出提示框...

    之前做一个android版的蓝牙 与血压计通讯的项目,遇到最大的难题就是自动配对. 上网查资料说是用反射createBond()和setPin(),但测试时进行配对还是会出现提示,但配对是成功了 我就 ...

  9. android 提示蓝牙无法配对,如何实现android蓝牙开发 自动配对连接,并不弹出提示框...

    之前做一个android版的蓝牙 与血压计通讯的项目,遇到最大的难题就是自动配对. 上网查资料说是用反射createBond()和setPin(),但测试时进行配对还是会出现提示,但配对是成功了 我就 ...

最新文章

  1. C# 获取属性的displayName
  2. ef mysql 外键 一对一_EFCore-一对一配置外键小记2
  3. 因为一个跨域请求,我差点丢了饭碗
  4. Python time和datetime时间戳和时间字符串相互转换
  5. 什么是openstack_谁是OpenStack大使?
  6. HTTP协议基本原理简介(三)
  7. android studio httpclient包导入,HttpClient不会导入Android Studio
  8. centos linux7 开启桌面命令,centos7如何在桌面打开终端
  9. Oracle中的sys用户和system用户
  10. 【Processing】使用vscode编辑运行Processing
  11. php匹配地址中的省市区,php 正则匹配省市区
  12. 2021-08-29
  13. js 类似发微博或者微信朋友圈的时间显示 刚刚 几天前
  14. 【原创】2009年太白山穿越
  15. 嵌入式linux开发,交叉编译qt4.8.5报错:not found (try using -rpath or -rpath-link)/home/ms/work/code/qt/opensourc
  16. vue移动端双击页面放大问题
  17. Python中datetime库的用法
  18. 2023北方工业大学计算机考研信息汇总
  19. 就业内推 | 锐捷专场!招网络工程师,HCIE证书优先,最高50k
  20. (附源码)计算机毕业设计ssm Sketch2Mod网站

热门文章

  1. java将大集合按照固定长度拆分为小集合
  2. #449 厂长来了:财务管理是企业信息化的前哨
  3. 2019年,人工智能领域有哪些突破值得期待?
  4. SOTA model
  5. 计算平均分并输出低于平均分的学生成绩
  6. 大二计科专业学生退役复学学习之路
  7. 笔记_Maya绑定基础_断开骨骼 And 骨骼的镜像
  8. React-connect用法
  9. 2021-07-30 Java练习题
  10. php中square是什么意思,square.php