【问题标题】:Android save BLE device to reconnect after app closeAndroid 保存 BLE 设备以在应用关闭后重新连接
【发布时间】:2017-04-18 15:30:52
【问题描述】:

我正在开发一个 android BLE 应用程序,我尝试在该应用程序和 BLE 设备之间建立稳定的连接。

为了实现这一点,我希望我的应用程序将 BLE 设备数据保存在共享首选项或某处。

应用程序关闭后,我希望我的应用程序检索此数据并尝试连接而不扫描设备。

我宁愿避免每次都扫描,因为扫描会给我带来很多问题并且需要时间。

怎么办?有没有办法保存 BLE 数据?

【问题讨论】:

    标签: android bluetooth bluetooth-lowenergy


    【解决方案1】:

    您需要将设备的蓝牙设备地址 (AB:CD:EF:01:02:03) 存储在共享首选项或 sqlite 数据库中。然后在您稍后重新启动应用程序以检索 BluetoothDevice 对象时使用https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getRemoteDevice(java.lang.String)。一旦你有了 BluetoothDevice 对象,你就可以像往常一样使用 connectGatt 方法。

    但是,您需要牢记一些未记录的事项。由于 Android 的 BLE API 中存在一些可怕的设计缺陷,因此无法判断给定地址是公共地址还是随机地址。 (您可以在https://devzone.nordicsemi.com/question/43670/how-to-distinguish-between-random-and-public-gap-addresses/ 阅读有关不同地址类型的更多信息)。 getRemoteDevice 方法应该采用附加参数“随机地址/公共地址”,但它没有。如果没有正确的地址类型,蓝牙控制器将无法连接到设备。

    Android 的 BLE 堆栈具有一些内部启发式来“猜测”地址是公开的还是随机的,但不幸的是,这在 Android 版本之间以及您使用 autoConnect=true 或 false 时会有所不同。但是,如果您已绑定设备 (https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createBond()),那么无论给定地址是公共地址还是随机地址,它将存储在其内部数据库中。如果您要连接的外围设备使用随机可解析地址,那么如果您使用绑定,它也可以处理。因此我强烈建议使用绑定。

    如果您不使用绑定,则需要在连接到设备之前进行扫描,因为当您开始扫描并检测到设备时,Android 的 BLE 堆栈会暂时(直到下次重新启动蓝牙)记住地址类型地址。

    【讨论】:

    • 你启发了我,谢谢,BLE真的很难理解。
    • @L.Gangemi 谢谢,这很有帮助。在过去的一年中,您是否了解了有关此随机与公共地址问题的任何其他信息。我目前正在尝试连接到使用随机寻址但该设备不支持绑定的设备。连接前扫描仍然是最佳/推荐的方法吗?知道为什么 Android 还没有解决这个问题吗?他们是否只是假设使用随机寻址的每个人也在使用绑定?
    • 不,他们没有修复任何东西。问题是原始堆栈可能是在 BLE 存在之前创建的。在 BT Classic 中,只有公共地址类型,因此他们选择在任何地方使用 BDADDR 作为整个堆栈中设备的标识符。这仍然是内部跟踪设备的方式,因此必须重写大部分堆栈以支持这一点,我认为 Android 蓝牙团队不会优先考虑这一点。
    • 设备重启后,关闭/打开蓝牙或手动清除蓝牙缓存,保存的设备(共享首选项或 locla DB 中保存的 MAC 地址)将无法连接。在尝试直接连接之前,您需要再次扫描设备。关注此medium.com/@martijn.van.welie/…
    • 只是打开/关闭蓝牙不会有任何伤害。然而,清除蓝牙缓存可能会擦除所有配对,因此 connectGatt 可能会由于地址类型不正确而失败。您应该使用 getBondState() 首先检查设备是否仍然配对。如果没有,您应该考虑重新扫描。
    【解决方案2】:

    我将继续 Emil 的回答。 感谢@Emil 的“大图”。

    • Google API 存在缺陷,您不能使用 getRemoteDevice(),因为它只了解 48 位地址,不了解所有 BLE 地址类型。
    • 如果设备很笨,则不能使用绑定(任何人都可以绑定到它)。

    因此,您唯一的解决方案是蓝牙扫描。
    但是,从 Android6 (Marshmallow) 开始,用户必须向使用蓝牙扫描的应用授予位置权限。如果您不允许,它将无法正常工作。
    因此,如果您购买蓝牙温度计(或心率监测器等),您必须允许该应用访问您手机(或平板电脑)的位置。 太荒谬了!
    @Emil 称之为“谷歌缺陷”。你也可以称之为“谷歌阴谋”。

    如果我是温度计设计师,我会添加一个按钮来接受绑定。这似乎很荒谬,因为该按钮只会被使用一次。
    [1]:https://www.polidea.com/blog/a-curious-relationship-android-ble-and-location/

    【讨论】:

    • 或者为什么根本没有任何按钮?只是允许使用“just works”一直绑定?如果您实际上没有任何敏感数据,而只是支持绑定来解决此问题。
    • 温度计通常没有按钮。这就是我写“添加按钮”的原因
    • 我应该添加另一个“不”,即为什么不完全跳过按钮并改用“正常工作”配对。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多