bluetooth - BLE Device Bonding Remove Automatically in Android -
we doing below process pair ble device.
connect() + discoverservices() + pairing(bonding) .
sometimes android os unpaired our bt device in weird way, is:
- without sending broadcast notification bonding state has changed
- even system bluetooth settings app thinks device still paired
- only bt restart (turning off , on via settings app) refreshes state , shows device not paired longer
when device paired action_bond_state change below.
[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 = 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-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
now when pairing removed os in weird way action_bond_state change below. . . . . bond state changed for: c2:69:e9:57:93:a4 new state: 10.
we immediate event of act=android.bluetooth.device.action.acl_disconnected flg=0x4000010 in our app.
what's important here, @ point lost pairing device , protected characteristics don't work longer. if restart bt using system settings app or bluetoothadapter::disable() , enable() can see not paired device.
what's funny, without bt restart, system settings app still thinks , shows paired device.
tested nexus 4 running 4.4.2, nexus 5 running 4.4.2 , samsung galaxy s4 running 4.3.
our expectation that:
- in case of unpairing there should system broadcast
- system preferences app should show current paring status without bt restart
we have observed , sniffed data in found our encryption set 0x000000 when our bonding removed os in weird way.
i have no idea whether still need or whether solved own problem (you know, since did post question in april), wanted go ahead , post workaround came because know other people having problem.
using nexus 7, ran same tests did , came same conclusion: if android tablet , remote device bonded, there high chance calling bluetoothgatt.discoverservices() both disconnect , unbond tablet remote device. but, parts of android os seemed oblivious unbonding; although broadcast receiver registered listen bonding changes notified bond between 2 devices had been broken, rest of android os considered bond still intact. since os considered tablet , remote device bonded, tablet not write of encrypted descriptors on remote device, giving write status of 15 (gatt_insufficient_encryption) whenever descriptor write attempted.
the solution
the key unpair nexus , remote device before have chance unpair in weird way. check see if tablet , remote device bonded right before start bluetooth low energy scan. if paired, remove bond using function below , start scan. unpairing 2 devices programmatically ensures android os aware no longer bonded and, therefore, go through usual bonding process.
below code use check see if remote device paired tablet , unpair if is:
// paired devices , put them in set bluetoothadapter mbluetoothadapter = bluetoothadapter.getdefaultadapter(); set<bluetoothdevice> paireddevices = mbluetoothadapter.getbondeddevices(); // loop through set of paired devices, checking see // if 1 of devices device need unpair // from. use device name, i'm sure can find // way determine whether or not device // -- if need to. :) (bluetoothdevice bt : paireddevices) { if (bt.getname().contains("string know has in device name")) { unpairdevice(bt); } } // function unpair 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()); } }
why waiting error , solving restarting bluetooth bad idea...
as have pointed out in question, restarting bluetooth after tablet , remote device mysteriously unbond each other forces android os realize no longer bonded remote deivce. original workaround used, became clear there 2 major problems came "solution":
- turning bluetooth on , off disconnect of devices connected tablet.
- turning bluetooth on , off wastes lot of time.
i restart bluetooth last resort. example, if unbonding error still miraculously occurred, choice restart bluetooth.
Comments
Post a Comment