在 Android 中自动删除 BLE 设备绑定 [英] BLE Device Bonding Remove Automatically in Android

查看:20
本文介绍了在 Android 中自动删除 BLE 设备绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We are doing below process to do pair with BLE Device.

连接()+发现服务()+配对(绑定).

Connect() + discoverServices() + Pairing(Bonding) .

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

Sometimes Android OS unpaired our BT device in a weird way, that is:

  • 不发送绑定状态已更改的广播通知
  • 即使是系统蓝牙设置应用也认为设备仍处于配对状态
  • 只有 bt restart(通过设置应用关闭和打开)刷新状态并显示设备不再配对

设备配对成功后,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 状态=504-09 18:18:27.365:E/millisUntilFinished(8380):millisUntilFinished = 1504-09 18:18:28.105:E/BelwithDeviceActor(8380):绑定状态更改为:C2:69:E9:57:93:A4 新状态:11 前:10

[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 Status=5 04-09 18:18:27.365: E/millisUntilFinished(8380): millisUntilFinished = 15 04-09 18:18:28.105: E/BelwithDeviceActor(8380): Bond state changed for: C2:69:E9:57:93:A4 new state: 11 previous: 10

04-09 18:18:28.105:E/millisUntilFinished(8380):millisUntilFinished = 2004-09 18:18:29.135:E/millisUntilFinished(8380):millisUntilFinished = 1804-09 18:18:30.135:E/millisUntilFinished(8380):millisUntilFinished = 1704-09 18:18:31.145:E/millisUntilFinished(8380):millisUntilFinished = 1604-09 18:18:32.145:E/millisUntilFinished(8380):millisUntilFinished = 15

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() - Device=C2:69:E9:57:93:A4 UUID=032a0000-0000-0000-0000-00000000 状态04-09 18:18:33.115:E/BelwithDeviceActor(8380):绑定状态更改为:C2:69:E9:57:93:A4 新状态:12 前:11

04-09 18:18:33.105: D/BluetoothGatt(8380): onCharacteristicWrite() - Device=C2:69:E9:57:93:A4 UUID=032a0000-0000-0000-0000-000000000000 Status=137 04-09 18:18:33.115: E/BelwithDeviceActor(8380): Bond state changed for: C2:69:E9:57:93:A4 new state: 12 previous: 11

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

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

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

Now when Pairing is removed by OS in weird way the ACTION_BOND_STATE is change as below. . . . . Bond state changed for: C2:69:E9:57:93:A4 new state: 10.

我们也在我们的 APP 中立即收到 act=android.bluetooth.device.action.ACL_DISCONNECTED flg=0x4000010 的事件.

we also get immediate event of act=android.bluetooth.device.action.ACL_DISCONNECTED flg=0x4000010 in our APP.

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

what's important here, at this point we just lost pairing with the device and protected characteristics don't work for us any longer. if we restart bt using system settings app or BluetoothAdapter::disable() and enable() we can see that we are not paired with the device.

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

what's funny, without the bt restart, system settings app still thinks and shows that we are paired with the device.

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

tested with nexus 4 running 4.4.2, nexus 5 running 4.4.2 and even Samsung galaxy s4 running 4.3.

我们的期望是:

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

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

We have also Observed and get the sniffed data in which we found that our encryption is set to 0x000000 when our bonding is removed by OS in weird way.

推荐答案

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

I have no idea whether you still need help or whether you eventually solved your own problem (you know, since you did post this question back in April), but I wanted to go ahead and post the workaround I came up with because I know other people are having this problem.

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

Using a Nexus 7, I ran basically the same tests you did and came to the same conclusion: If the Android tablet and the remote device were already bonded, there was a high chance that calling BluetoothGatt.discoverServices() would both disconnect and unbond the tablet from the remote device. But, certain parts of the Android OS seemed completely oblivious to the unbonding; although the Broadcast Receiver you registered to listen for bonding changes was notified that the bond between the two devices had been broken, the rest of the Android OS considered the bond to still be intact. Since the OS considered the tablet and the remote device to be bonded, the tablet could not write to any of the encrypted descriptors on the remote device, giving a write status of 15 (GATT_INSUFFICIENT_ENCRYPTION) whenever a descriptor write was attempted.

解决方案

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

The key is to unpair the Nexus and the remote device before they have the chance to unpair themselves in that weird way. What I do is check to see if the tablet and the remote device are bonded right before I start a Bluetooth Low Energy scan. If they are paired, I remove the bond using the function below and then start the scan. Unpairing the two devices programmatically ensures that the Android OS is aware that they are no longer bonded and, therefore, will go through the usual bonding process.

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

Below is the code is use to check to see if the remote device is paired with the tablet and unpair it if it is:

// 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 操作系统意识到它不再绑定到远程设备.这是我最初使用的解决方法,但很快就发现这个解决方案"带来了两个主要问题:

As you have already pointed out in your question, restarting the Bluetooth after the tablet and the remote device mysteriously unbond from each other forces the Android OS to realize that it is no longer bonded to the remote deivce. This was the original workaround I used, but it soon became clear that there were two major problems that came with this "solution":

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

我只会在万不得已的情况下重新启动蓝牙.例如,如果仍然奇迹般地发生解绑错误,您唯一的选择就是重新启动蓝牙.

I would only restart the Bluetooth as a last resort. For example, if the unbonding error still miraculously occurred, your only choice would be to restart the Bluetooth.

这篇关于在 Android 中自动删除 BLE 设备绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆