BLEデバイスとペアリングするために以下のプロセスを実行しています。
Connect()+ DiscoverServices()+ Pairing(Bonding)。
時々Android OSは奇妙な方法で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):ボンド状態が変更されましたfor:C2:69:E9:57:93:A4新しい状態:11前:1
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):結合状態が変更されました:C2:69:E9:57:93:A4新しい状態:12前:11
04-09 18:18:33.115:I/System.out(8380):unregisterReceiver true
これで、OSによってペアリングが奇妙な方法で削除されると、ACTION_BOND_STATEが次のように変更されます。 。 。 。 。 ボンド状態が変更されました:C2:69:E9:57:93:A4新しい状態:10。
また、APPでact = Android.bluetooth.device.action.ACL_DISCONNECTED flg = 0x4000010の即時イベントを取得します。
ここで重要なのは、この時点でデバイスとのペアリングが失われ、保護された特性が機能しなくなったことです。システム設定アプリまたはBluetoothAdapter :: disable()とenable()を使用してbtを再起動すると、デバイスとペアリングされていないことがわかります。
面白いことに、BTを再起動しなくても、システム設定アプリはデバイスとペアリングされていることを認識して表示します。
4.4.2を実行しているネクサス4、4.4.2を実行しているネクサス5、さらに4.3を実行しているサムスンギャラクシーs4でテストされました。
私たちの期待は次のとおりです。
また、OSによって奇妙な方法でボンディングが削除されたときに、暗号化が0x000000に設定されていることがわかった、スニッフィングされたデータを観察して取得しました。
まだ助けが必要なのか、最終的に自分の問題を解決したのかはわかりませんが(4月にこの質問を投稿したので)、他のことを知っているので、思いついた回避策を投稿したいと思いました。人々はこの問題を抱えています。
Nexus 7を使用して、基本的に同じテストを実行し、同じ結論に達しました。Androidタブレットとリモートデバイスがすでに結合されている場合、BluetoothGattを呼び出す可能性が高いです。 DiscoverServices()は、タブレットをリモートデバイスから切断および結合解除します。ただし、Android OSの特定の部分は、結合解除を完全に認識していないように見えました。ただし、結合の変更をリッスンするために登録したブロードキャストレシーバーは2つのデバイス間の結合が切断されたことが通知されたため、残りのAndroid OSは結合がまだ損なわれていないと見なしました。OSはタブレットとリモートデバイスが結合していると見なしたため、タブレットはリモートデバイス上の暗号化された記述子のいずれにも書き込むことができず、記述子の書き込みが試行されるたびに書き込みステータスが15(GATT_INSUFFICIENT_ENCRYPTION)になりました。
解決策
重要なのは、Nexusとリモートデバイスのペアリングを解除することです前彼らはその奇妙な方法で自分自身のペアリングを解除する機会があります。私がしていることは、Bluetooth Low Energyスキャンを開始する直前に、タブレットとリモートデバイスが結合されているかどうかを確認することです。ペアになっている場合は、以下の機能を使用して結合を解除し、スキャンを開始します。 2つのデバイスのペアリングをプログラムで解除すると、Android OSは、デバイスが結合されなくなったことを認識し、通常の結合プロセスを実行します。
以下は、リモートデバイスがタブレットとペアリングされているかどうかを確認し、ペアリングされている場合はペアリングを解除するために使用されるコードです。
// 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 OSは、リモートデバイスに結合されなくなったことを認識します。 。これは私が使用した元の回避策でしたが、この「解決策」には2つの大きな問題があることがすぐに明らかになりました。
最後の手段としてBluetoothを再起動するだけです。たとえば、それでも奇跡的に剥離エラーが発生した場合は、Bluetoothを再起動するしかありません。
同じ問題が発生し、SDK v 23以降、「connectGatt」に新しい「transport」引数(接続のトランスポートプロトコルを定義)があることがわかりました。したがって、デバイスをペアリングする場合は、「TRANSPORT_BREDR」を使用する必要があります。 、ボンディングせずに周辺機器にのみ接続する場合は、「TRANSPORT_LE」ドキュメントを使用します: https://developer.Android.com/reference/Android/bluetooth/BluetoothDevice.html#connectGatt(Android.content.Context 、boolean、Android.bluetooth.BluetoothGattCallback、int)