I'm trying to connect an Android Tablet to an already bonded BLE device via BluetoothDevice::connectGatt(...)
, but the BluetoothParingDialog gets called again twice.
The BLE device is based on the Nordic nRF5 series.
I created a very simplified Android app (targetSdk 30) to isolate the problem:
Manifest:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true"/>
Scan for the device:
BluetoothManager bluetoothManager = (BluetoothManager)getContext().getSystemService(BLUETOOTH_SERVICE);
bluetoothLeScanner = bluetoothManager.getAdapter().getBluetoothLeScanner();
bluetoothLeScanner.startScan(scanCallback);
Scan callback:
ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();
if (device != null) {
String deviceName = device.getName();
if (deviceName != null) {
if (deviceName.startsWith("MY_BLE_DEVICE")) {
bluetoothLeScanner.stopScan(scanCallback);
bluetoothDevice = device;
TryConnect();
}
}
}
super.onScanResult(callbackType, result);
}
private void TryConnect() {
if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
bluetoothDevice.connectGatt(getContext(), false, new BluetoothGattCallback(){});
} else {
bluetoothDevice.createBond();
}
}
};
And here the broadcast receiver for connecting after the first bonding:
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
int state = (int)intent.getExtras().get(BluetoothDevice.EXTRA_BOND_STATE);
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action) && !isConnection){
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
isConnection = true;
TryConnect();
}
}
}
};
On first time, everything works fine. The device starts bonding via BluetoothDevice::createBond()
, the dialog pops-up and after pressing "pair", I can connect to the device. Afterwards, it's also displayed as "Paired" in the Android Bluetooth Settings.
On the second time, the scanner finds the device, and I'm calling directly connectGatt()
-> The Paring-Dialog gets displayed again (and once again if I press "Pair"). Also, the device is not paired anymore (see in the logs).
This also happens if I pair the device at first via Android Bluetooth Settings.
Following the logcat output directly after calling connectGatt(..)
2022-07-27 16:37:33.145 21289-21289/com.example.bletestapp I/BluetoothAdapter: STATE_ON
2022-07-27 16:37:33.154 21289-21289/com.example.bletestapp D/BluetoothGatt: connect() - device: DE:D6:D2:33:40:03, auto: false
2022-07-27 16:37:33.155 21289-21289/com.example.bletestapp I/BluetoothAdapter: isSecureModeEnabled
2022-07-27 16:37:33.156 2777-4160/? D/BtConfig.SecureMode: isSecureModeOn:false
2022-07-27 16:37:33.156 21289-21289/com.example.bletestapp D/BluetoothGatt: registerApp()
2022-07-27 16:37:33.160 21289-21289/com.example.bletestapp D/BluetoothGatt: registerApp() - UUID=ca7f6fdc-54b5-4412-9ce8-82044123d264
2022-07-27 16:37:33.163 2777-4160/? D/BtGatt.GattService: registerClient(com.example.bletestapp) - UUID=ca7f6fdc-54b5-4412-9ce8-82044123d264
2022-07-27 16:37:33.165 2777-4160/? D/BtGatt.ContextMap: add() - appUid: 10426, appPid: 21289, appName: com.example.bletestapp
2022-07-27 16:37:33.166 2777-3876/? I/bt_stack: [INFO:gatt_api.cc(950)] GATT_Register ca7f6fdc-54b5-4412-9ce8-82044123d264
2022-07-27 16:37:33.166 2777-3876/? I/bt_stack: [INFO:gatt_api.cc(994)] allocated gatt_if=13
2022-07-27 16:37:33.166 2777-2979/? D/BtGatt.GattService: onClientRegistered() - UUID=ca7f6fdc-54b5-4412-9ce8-82044123d264, clientIf=13
2022-07-27 16:37:33.168 21289-23039/com.example.bletestapp D/BluetoothGatt: onClientRegistered() - status=0 clientIf=13
2022-07-27 16:37:33.218 21289-21289/com.example.bletestapp I/BluetoothAdapter: STATE_ON
2022-07-27 16:37:33.218 21289-21289/com.example.bletestapp D/BluetoothLeScanner: could not find callback wrapper
2022-07-27 16:37:33.223 2777-4160/? D/BtGatt.GattService: clientConnect(com.example.bletestapp) - address = 33:4, isDirect=true transport =0 set own addr = false own addr type:0, clientIf: 13, opportunistic=false, phy: 1
2022-07-27 16:37:33.225 2777-3876/? W/bt_btm: BTM_SecAddBleDevice: dev_type=0x2
2022-07-27 16:37:33.225 2777-3876/? E/bt_stack: [ERROR:gatt_api.cc(1150)] GATT_Connectgatt_if=13, address=de:d6:d2:33:40:03, is_direct=1, opportunistic=0
2022-07-27 16:37:33.226 2777-3876/? W/bt_btm: btm_find_dev_by_identity_addr find pseudo->random match with diff addr type: 1 vs 0
2022-07-27 16:37:33.226 2777-3876/? W/bt_btm: btm_find_dev_by_identity_addr find pseudo->random match with diff addr type: 1 vs 0
2022-07-27 16:37:33.226 2777-3876/? W/bt_btm: btm_ble_enable_resolving_list() rl_state = 0xb, rl_mask = 0x1
2022-07-27 16:37:33.226 773-773/? D/vendor.qti.bluetooth@1.0-ibs_handler: SerialClockVote: vote for UART CLK ON
2022-07-27 16:37:33.227 773-773/? D/vendor.qti.bluetooth@1.0-wake_lock: Acquire wakelock is acquired
2022-07-27 16:37:33.227 773-773/? I/vendor.qti.bluetooth@1.0-ibs_handler: DeviceWakeUp: Writing IBS_WAKE_IND
2022-07-27 16:37:33.230 773-3872/? I/vendor.qti.bluetooth@1.0-ibs_handler: ProcessIbsCmd: Received IBS_WAKE_ACK: 0xFC
2022-07-27 16:37:33.230 773-3872/? I/vendor.qti.bluetooth@1.0-ibs_handler: ProcessIbsCmd: Signal wack_cond_
2022-07-27 16:37:33.230 773-773/? D/vendor.qti.bluetooth@1.0-ibs_handler: DeviceWakeUp: Unblocked from waiting for FC
2022-07-27 16:37:33.231 773-3872/? I/vendor.qti.bluetooth@1.0-ibs_handler: ProcessIbsCmd: Received IBS_WAKE_IND: 0xFD
2022-07-27 16:37:33.231 773-3872/? I/vendor.qti.bluetooth@1.0-ibs_handler: ProcessIbsCmd: Writing IBS_WAKE_ACK
2022-07-27 16:37:33.258 2805-2805/? I/ViewRootImpl@bceb956[Toast]: Relayout returned: old=(0,36,1200,1920) new=(422,1762,778,1824) req=(356,62)0 dur=13 res=0x7 s={true 500290883584} ch=true fn=-1
2022-07-27 16:37:33.259 2777-3876/? W/bt_l2cap: l2cble_conn_comp: HANDLE=6 addr_type=1 conn_interval=36 slave_latency=0 supervision_tout=500
2022-07-27 16:37:33.259 2777-3876/? W/bt_l2cap: l2cu_initialize_fixed_ccb: don't cancel l2c_lcb_timer
2022-07-27 16:37:33.259 2777-3876/? W/bt_btm: btm_ble_disable_resolving_list() rl_state = 0xb, rl_mask = 0x1, to_resume = 1
2022-07-27 16:37:33.267 2777-3876/? D/IOP_DB_BT: db_query_create: id EnforceMasterRole :: key KEY_BDADDR
2022-07-27 16:37:33.268 2777-3876/? D/IOP_DB_BT: db_query_add_key: key KEY_DIR_ALL
2022-07-27 16:37:33.268 2777-3876/? D/IOP_DB_BT: db_query_execute: result 1
2022-07-27 16:37:33.269 2777-3876/? W/bt_btif: bta_dm_acl_change info: 0x0
2022-07-27 16:37:33.290 2777-2979/? E/BluetoothRemoteDevices: Remote class is UNCATEGORIZED
2022-07-27 16:37:33.290 2777-2979/? I/BluetoothBondStateMachine: bondStateChangeCallback: Status: 0 Address: DE:D6:D2:33:40:03 newState: 1
2022-07-27 16:37:33.294 1210-3535/? D/SecContentProvider: query(), uri = 4 selection = bluetoothLogForRemote
2022-07-27 16:37:33.294 1210-3535/? D/SecContentProvider: called from android.uid.bluetooth:1002
2022-07-27 16:37:33.295 2777-2979/? I/BluetoothBondStateMachine: sspRequestCallback: [B@f395de name: [B@714a3bf cod: 7936 pairingVariant 2 passkey: ******
2022-07-27 16:37:33.296 2777-2979/? E/bt_btif: remote name callback registration fail.
2022-07-27 16:37:33.298 2777-3638/? D/BluetoothAdapterService: updateDataBase() bondstate : 11
2022-07-27 16:37:33.298 2777-3638/? E/BluetoothAdapterService: updateDataBase - newState is bonding. return.
Is there a way to get the reason, why the dialog is shown twice? Since it's hidden in the SDK, I can't get the stack trace to figure it out in detail. Does the BLE device miss something in the handshake / connection procedure which could lead to this behavior? Could it be a timing problem or key exchange failure? If more information of the BLE device is necessary, I can submit it later.