BLE:通过BluetoothAdapter#getRemoteDevice()与扫描获取BluetoothDevice

时间:2018-04-28 20:49:12

标签: android bluetooth bluetooth-lowenergy unreliable-connection

情景:

鉴于此,该设备始终处于开启状态,并且每秒都会进行蓝牙低功耗广告。
我必须实现Android平板电脑的应用程序,通过蓝牙低功耗连接到此设备,发送一些命令,然后断开它。
最低Android版本:效果最好的版本,我可以自由决定。 我从API 21(Android 5.0,Lollipop)开始

问题:

BLE堆栈存在的问题也给我带来了麻烦:我想使用 BluetoothAdapter#getRemoteDevice(MACAddress:String)方法检索的对象发出成功的直接连接,它总是失败。

我的研究结果:

以下是我发现并且看起来很有用的问题/答案/帖子(也许这些会对某人有帮助):

问题:

除此之外,我查看了BluetoothDevice的源代码,并且我发现 connectGatt()方法的 Context 参数是而不是< / em>全部使用:
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothDevice.java#1899
想知道这是否是BLE堆栈存在缺陷的原因之一?

另外,我不明白扫描程序检索的 BluetoothDevice 对象与 BluetoothAdapter#getRemoteDevice(MACAddress:String)方法检索的对象之间的区别是什么。
如果我通过扫描在设备上发出直接连接( autoconnect 参数设置为 false ,则调用 connectGatt()),通常连接成功。但是,当使用 getRemoteDevice()检索的对象时,直接连接总是失败( status = 133,timeout )。

由于我想要连接的设备每秒都会自我宣传,我希望直接/大部分时间都可以直接连接,就像扫描一样。 因为后台连接( autoconnect参数设置为true )非常慢,所以我不能依赖它。
此外,由于扫描不可靠且速度慢,因此无法在每次应用程序启动时强制用户等待。

总结我的问题:

  • connectGatt()方法的 Context 参数根本使用 - 这可能是导致漏洞的原因之一BLE堆栈有?我想有人把它放在那里是有充分理由的。
  • 扫描程序检索的 BluetoothDevice 对象与 BluetoothAdapter#getRemoteDevice(MACAddress:String)方法检索的 BluetoothDevice 对象有什么区别?

1 个答案:

答案 0 :(得分:1)

  1. 在早期的Android版本中使用了context参数,但显然不再需要了。您仍应传递有效的上下文以与早期版本兼容,如果他们决定再次使用它,则应更新。

  2. 应该没有任何区别。但是,如果您只是通过蓝牙设备地址连接,您会注意到API中无法传递地址类型(公共或随机)的缺陷。因此,如果您尝试连接到静态随机地址,除非您第一次扫描设备,否则可能会失败。这是因为Android会保留地址缓存以及最新广告中的地址类型。因此,请先尝试扫描并确保看到要连接的设备。然后尝试使用BluetoothAdapter#getRemoteDevice(MACAddress:String)进行连接。