コンテンツ
パート#4(ボンディング)、あなたはここにいます
では 前の記事、 私たちは、有効/無効の通知およびキューコマンドを、読み取り/書き込み操作を考え出しました。この記事では、ペアリングデバイスについて説明し ます (トランスレータのメモ-さらに「ボンディング」という用語を使用します)。
ボンディング
一部のデバイスは、正しく機能するためにボンディングが必要です。技術的には、これは安全なデータ交換のために暗号化キーが生成、交換、保存されることを意味します。ボンディング手順を開始するときに、Androidはユーザーに同意、PINコード、またはパスフレーズを要求する場合があります。次の接続では、Androidはデバイスがペアリングされ、暗号化キーがユーザーの介入なしに秘密裏に交換されることをすでに認識しています。ボンディングを使用すると、接続が暗号化されるため、デバイスへの接続がより安全になります。
bonding Google, , bonding. createBond()
. , iOS CoreBluetooth
! createBond()
? , , bonding, . Bluetooth , – bonding. . , , , .
bonding:
Android bonding. Android bonding , , bonding, / .
createBond()
(. : , - . , Samsung -, );
, bonding. / , . Android bonding;
bonding. bonding , ;
, ,
createBond()
bonding . .
bonding?
, bonding:
, , bonding, ;
«» . , bonding. / , bonding – /
INSUFFICIENT_AUTHENTICATION
. iOS.
bonding
createBond()
. , iOS, . Bluetooth .
.
Bonding
bonding , onConnectionStateChange
bonding BOND_BONDING
. bonding , discoverServices()
, bonding ! . onConnectionStateChanged
:
// Take action depending on the bond state
if(bondstate == BOND_NONE || bondstate == BOND_BONDED) {
// Connected to device, now proceed to discover it's services
...
} else if (bondstate == BOND_BONDING) {
// Bonding process has already started let it complete
Log.i(TAG, "waiting for bonding to complete");
}
, bonding, BroadcastReceiver
ACTION_BOND_STATE_CHANGED
connectGatt
. bonding.
context.registerReceiver(bondStateReceiver,
new IntentFilter(ACTION_BOND_STATE_CHANGED));
private final BroadcastReceiver bondStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Ignore updates for other devices
if (bluetoothGatt == null || !device.getAddress().equals(bluetoothGatt.getDevice().getAddress()))
return;
// Check if action is valid
if(action == null) return;
// Take action depending on new bond state
if (action.equals(ACTION_BOND_STATE_CHANGED)) {
final int bondState = intent.getIntExtra(EXTRA_BOND_STATE, ERROR);
final int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1);
switch (bondState) {
case BOND_BONDING:
// Bonding started
...
break;
case BOND_BONDED:
// Bonding succeeded
...
break;
case BOND_NONE:
// Oh oh
...
break;
}
}
}
};
bonding, (service discovery), , :
case BOND_BONDED:
// Bonding succeeded
Log.d(TAG, "bonded");
// Check if there are services
if(bluetoothGatt.getServices().isEmpty()) {
// No services discovered yet
bleHandler.post(new Runnable() {
@Override
public void run() {
Log.d(TAG, String.format("discovering services of '%s'", getName()));
boolean result = bluetoothGatt.discoverServices();
if (!result) {
Log.e(TAG, "discoverServices failed to start");
}
}
});
}
, bonding .
Bonding /
bonding / , / GATT_INSUFFICIENT_AUTHENTICATION
. Android-6, 7 onCharacteristicRead
/onCharacteristicWrite
, bonding Android. Android-8 Android bonding. Android-6, 7 / . , bonding.
, :
public void onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, int status) {
// Perform some checks on the status field
if (status != GATT_SUCCESS) {
if (status == GATT_INSUFFICIENT_AUTHENTICATION ) {
// Characteristic encrypted and needs bonding,
// So retry operation after bonding completes
// This only happens on Android 5/6/7
Log.w(TAG, "read needs bonding, bonding in progress");
return;
} else {
Log.e(TAG, String.format(Locale.ENGLISH,"ERROR: Read failed for characteristic: %s, status %d", characteristic.getUuid(), status));
completedCommand();
return;
}
}
...
bonding , :
case BOND_BONDED:
// Bonding succeeded
Log.d(TAG, "bonded");
// Check if there are services
...
// If bonding was triggered by a read/write, we must retry it
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
if (commandQueueBusy && !manuallyBonding) {
bleHandler.postDelayed(new Runnable() {
@Override
public void run() {
Log.d(TAG, "retrying command after bonding");
retryCommand();
}
}, 50);
}
}
bonding
, createBond
, , . , ? iOS createBond()
, – bonding , iOS. iOS. BLE , createBond()
- .
createBond
, , bonding BroadcastReceiver
. (bonding ), createBond()
, bonding .
createBond()
– . BluetoothDevice
MAC-, (bonding). … ! (. : , , , ).
bonding
Android, Bluetooth . , bonding .
.
, bonding . , removeBond()
, Java:
try {
Method method = device.getClass().getMethod("removeBond", (Class[]) null);
result = (boolean) method.invoke(device, (Object[]) null);
if (result) {
Log.i(TAG, "Successfully removed bond");
}
return result;
} catch (Exception e) {
Log.e(TAG, "ERROR: could not remove bond");
e.printStackTrace();
return false;
}
bonding
BLE bonding . , bonding :
bonding
B bonding
, bonding .
bonding BOND_NONE
BroadcastReceiver
. bonding, :
case BOND_NONE:
if(previousBondState == BOND_BONDING) {
// Bonding failed
...
} else {
// Bond lost
...
}
disconnect();
break;
bonding, , . , Android bonding. .
, . bonding, , Bluetooth . bonding, Android , , . .
Pairing
. : «pairing», «» - .
Android bonding, . «», (. : Samsung-S9, Android-10, , , , ). Google ( , Android ), .
Pairing :
;
;
« »;
Bluetooth .
«» 60 . , . , , . , . UI -! () ! Samsung - ( JustWorks) , . PIN- . . !
, , , . , . :
public void startPairingPopupHack() {
String manufacturer = Build.MANUFACTURER;
if(!manufacturer.equals("samsung")) {
bluetoothAdapter.startDiscovery();
callBackHandler.postDelayed(new Runnable() {
@Override
public void run() {
Log.d(TAG, "popup hack completed");
bluetoothAdapter.cancelDiscovery();
}
}, 1000);
}
}
– BLE . .
, bonding !
…
BLE Android (. : -, BLE Android, ). BLE . BLE, . !
BLEでの作業が待ちきれませんか?私のBlessedforAndroidライブラリを試してみてください 。この一連の記事のすべてのアプローチを採用し、アプリケーションでBLEを簡単に操作できるようにします。