android - BLE 设备绑定(bind)在 Android 中自动删除

标签 android bluetooth bluetooth-lowenergy

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

Connect() + discoverServices() + 配对(绑定(bind))。

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

  • 不发送绑定(bind)状态已更改的广播通知
  • 甚至系统蓝牙设置应用程序也认为设备仍然配对
  • 只有 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): 绑定(bind)状态更改为: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): 绑定(bind)状态更改为: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 的即时事件。

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

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

使用运行 4.4.2 的 nexus 4、运行 4.4.2 的 nexus 5 甚至运行 4.3 的三星 galaxy s4 进行测试。

我们的期望是:

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

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

最佳答案

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

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

解决方案

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

下面是用于检查远程设备是否与平板电脑配对并取消配对的代码:

// 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()); }
}



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

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

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

我只会在万不得已时重新启动蓝牙。例如,如果仍然奇迹般地出现解绑错误,那么您唯一的选择就是重启蓝牙。

关于android - BLE 设备绑定(bind)在 Android 中自动删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23076641/

相关文章:

android - Android 中用于蓝牙的 API 查找我个人资料中的即时警报服务

iOS- BLE <CBCharacteristic : does not specify the "Write Without Response" property - ignoring response-less write

java - 为什么 IntentReceiverLeaked?

flutter - 如何在flutter中使用flutter blue接收数据

java - android.R.* 的视觉资源?

java - ListView : disabling clicking/focus

bluetooth-lowenergy - BLE 规范是否允许在广告数据和扫描响应中使用制造商广告类型?

swift - 使用 Swift 中的按钮通过蓝牙发送数据

android - 如何在 Android 应用程序中对 Facebook 照片发表评论?

java - 不幸的是,应用程序已停止