Ответ 1
Я понятия не имею, нужна ли вам помощь или вы в конечном итоге решили свою проблему (вы знаете, поскольку вы отправили этот вопрос еще в апреле), но я хотел пойти дальше и опубликовать обходное решение, с которым я столкнулся, Я знаю, что у других людей есть эта проблема.
Используя Nexus 7, я провел в основном те же тесты, что и вы, и пришел к такому же выводу: Если планшет Android и удаленное устройство уже были связаны, существует высокая вероятность того, что вызов BluetoothGatt.discoverServices() будет отключать и отключать планшет от удаленного устройства. Но некоторые части ОС Android казались совершенно забытыми для несвязанных; хотя широковещательный приемник, который вы зарегистрировали для прослушивания изменений связи, был уведомлен о том, что связь между этими двумя устройствами была нарушена, остальная часть ОС Android считала, что облигация по-прежнему остается нетронутой. Поскольку ОС рассматривала планшет и удаленное устройство для соединения, планшет не мог записывать на любой из зашифрованных дескрипторов на удаленном устройстве, предоставляя статус записи 15 (GATT_INSUFFICIENT_ENCRYPTION) всякий раз, когда была предпринята попытка записи дескриптора.
Решение
Ключ к устранению неполадок Nexus и удаленного устройства до, у них есть шанс отключить себя этим странным способом. Что я делаю, это проверить, чтобы убедиться, что планшет и удаленное устройство связаны до того, как я начну сканирование с низкой энергией Bluetooth. Если они спарены, я удаляю связь, используя приведенную ниже функцию, а затем запускаю сканирование. Отказ от двух устройств программным образом гарантирует, что ОС 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()); }
}
Почему ожидание ошибки, а затем ее решение путем перезапуска Bluetooth - это плохая идея...
Как вы уже указывали в своем вопросе, перезапуск Bluetooth после того, как планшет и удаленное устройство таинственно не связаны друг с другом, вынуждают ОС Android осознать, что он больше не связан с удаленным девайсом. Это было первоначальное решение, которое я использовал, но вскоре стало ясно, что с этим "решением" были две серьезные проблемы:
- Включение и выключение Bluetooth приведет к отключению всех устройств, подключенных к планшету.
- Включение и выключение Bluetooth тратит лот.
Я бы только перезапустил Bluetooth как последнее средство. Например, если несвязанная ошибка все же чудесным образом произошла, единственным выбором будет перезапуск Bluetooth.