在 Android 中自动删除 BLE 设备绑定

Posted

技术标签:

【中文标题】在 Android 中自动删除 BLE 设备绑定【英文标题】:BLE Device Bonding Remove Automatically in Android 【发布时间】:2014-04-15 06:59:44 【问题描述】:

我们正在执行以下过程来与 BLE 设备配对。

Connect() + discoverServices() + Pairing(Bonding)。

有时 android 操作系统会以一种奇怪的方式取消配对我们的 BT 设备,即:

不发送绑定状态已更改的广播通知 甚至系统蓝牙设置应用程序都认为设备仍然配对 只有 bt 重启(通过设置应用关闭和打开)刷新状态并显示设备不再配对

设备配对成功后,ACTION_BOND_STATE 的变化如下。

[6:19:28 PM] Himen Patel:04-09 18:18:27.325:D/BluetoothGatt(8380):onCharacteristicWrite() - Device=C2:69:E9:57:93:A4 UUID=860b2c07 -e3c5-11e2-a28f-0800200c9a66 状态=5 04-09 18:18:27.365:E/millisUntilFinished(8380):millisUntilFinished = 15 04-09 18:18:28.105: E/BelwithDeviceActor(8380): 键状态更改为:C2:69:E9:57:93:A4 新状态:11 以前:10

04-09 18:18:28.105:E/millisUntilFinished(8380):millisUntilFinished = 20 04-09 18:18:29.135:E/millisUntilFinished(8380):millisUntilFinished = 18 04-09 18:18:30.135:E/millisUntilFinished(8380):millisUntilFinished = 17 04-09 18:18:31.145:E/millisUntilFinished(8380):millisUntilFinished = 16 04-09 18:18:32.145:E/millisUntilFinished(8380):millisUntilFinished = 15

04-09 18:18:33.105: D/BluetoothGatt(8380): onCharacteristicWrite() - 设备=C2:69:E9:57:93:A4 UUID=032a0000-0000-0000-0000-000000000000 状态=137 04-09 18:18:33.115:E/BelwithDeviceActor(8380):键状态更改为:C2:69:E9:57:93:A4 新状态:12 以前:11

04-09 18:18:33.115: I/System.out(8380): unregisterReceiver true

现在,当操作系统以奇怪的方式删除配对时,ACTION_BOND_STATE 会发生如下变化。 . . . . 键状态更改为:C2:69:E9:57:93:A4 新状态:10。

在我们的 APP 中,我们还会收到 act=android.bluetooth.device.action.ACL_DISCONNECTED flg=0x4000010 的即时事件。

这里重要的是,此时我们只是失去了与设备的配对,受保护的特性不再对我们起作用。 如果我们使用系统设置 app 或 BluetoothAdapter::disable() 和 enable() 重新启动 bt,我们可以看到我们没有与设备配对。

有趣的是,不重启bt,系统设置应用仍然认为并显示我们与设备配对。

测试了运行 4.4.2 的 nexus 4、运行 4.4.2 的 nexus 5 甚至运行 4.3 的三星 Galaxy s4。

我们的期望是:

在取消配对的情况下应该有系统广播 系统偏好设置应用程序应该显示当前的配对状态,即使没有 bt 重启

我们还观察并获得了嗅探数据,我们发现当我们的绑定被操作系统以奇怪的方式删除时,我们的加密设置为 0x000000。

【问题讨论】:

Android 错误跟踪器中有一个错误,您应该可以搜索它。 我在装有 kit kat 4.4.3 的 Moto G 中也遇到了这个问题,您是否找到了解决此问题的方法? 【参考方案1】:

我不知道您是否仍然需要帮助,或者您是否最终解决了自己的问题(您知道,因为您确实在 4 月份发布了这个问题),但我想继续发布我想出的解决方法,因为我知道其他人也有这个问题。

使用 Nexus 7,我进行了与您所做的基本相同的测试并得出了相同的结论: 如果 Android 平板电脑和远程设备已经绑定,调用 BluetoothGatt.discoverServices() 很有可能会断开平板电脑与远程设备的绑定并解除绑定。但是,Android OS 的某些部分似乎完全没有注意到这种分离;尽管您注册用于监听绑定更改的广播接收器被通知两台设备之间的绑定已被破坏,但 Android 操作系统的其余部分认为绑定仍然完好无损。由于操作系统认为平板电脑和远程设备是绑定的,因此平板电脑无法写入远程设备上的任何加密描述符,每当尝试写入描述符时,都会给出写入状态 15 (GATT_INSUFFICIENT_ENCRYPTION)。

解决方案

关键是在 Nexus 和远程设备有机会以这种奇怪的方式解除配对之前解除配对。我要做的是在开始低功耗蓝牙扫描之前检查平板电脑和远程设备是否已绑定。如果它们配对,我使用下面的功能删除键,然后开始扫描。以编程方式取消两个设备的配对可确保 Android 操作系统知道它们不再绑定,因此将执行通常的绑定过程。

以下代码用于检查远程设备是否与平板电脑配对,如果配对则取消配对:

// Get the paired devices and put them in a Set
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();

// Loop through the Set of paired devices, checking to see
// if one of the devices is the device you need to unpair
// from. I use the device name, but I'm sure you can find
// another way to determine whether or not its your device
// -- if you need to. :)
for (BluetoothDevice bt : pairedDevices) 
        if (bt.getName().contains("String you know has to be in device name")) 
            unpairDevice(bt);
        


// Function to unpair from passed in device
private void unpairDevice(BluetoothDevice device) 
    try 
        Method m = device.getClass().getMethod("removeBond", (Class[]) null);
        m.invoke(device, (Object[]) null);
     catch (Exception e)  Log.e(TAG, e.getMessage()); 

为什么等待错误然后通过重新启动蓝牙来解决它是一个坏主意...

正如您在问题中已经指出的那样,在平板电脑和远程设备神秘地解除绑定后重新启动蓝牙会迫使 Android 操作系统意识到它不再与远程设备绑定。这是我最初使用的解决方法,但很快就发现这个“解决方案”存在两个主要问题:

    打开和关闭蓝牙会断开连接到平板电脑的所有设备。 打开和关闭蓝牙会浪费很多时间。

我只会重新启动蓝牙作为最后的手段。例如,如果解绑错误仍然奇迹发生,您唯一的选择就是重新启动蓝牙。

【讨论】:

【参考方案2】:

我们遇到了同样的问题,我们发现“connectGatt”具有新的“transport”参数(定义连接的传输协议),从 SDK v 23 开始。 所以如果你想配对你的设备,你应该使用“TRANSPORT_BREDR”,如果你只想连接到外围设备而不绑定 - 使用“TRANSPORT_LE” 文档:https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int)

【讨论】:

默认传输层是自动的。这不按预期工作吗?绑定不仅适用于标准蓝牙。它也适用于 LE(参见:“BF,“Bonding_Flags””):bluetooth.com/blog/…

以上是关于在 Android 中自动删除 BLE 设备绑定的主要内容,如果未能解决你的问题,请参考以下文章

BLE在Android上没有绑定的配对

蓝牙服务器重启后 BLE 配对出现问题

设备配对时,Android BLE 读取数据速率很慢

Android和双模蓝牙设备:与BR / EDR(经典)配对时未找到自定义BLE服务

适用于Android的蓝牙低功耗(BLE)外设应用程序

如何在 Android 4.3 API 18 中获取绑定设备?