问题描述
我正在尝试确定使用蓝牙低功耗与支持BLE的设备进行通信的应用程序出了什么问题。 令人发疯的是,该问题仅发生在某些设备上,例如Europa的Motorola Moto G3和中国的Samsung S5,而与Europa的Samsung S5,Europa的HTC One M7和中国的MI W3可以正常使用。
当它不起作用时,在成功写入描述符之后一切都会停止,因为从未调用过相应的onDescritorWrite(...)回调。 大概与设置加密失败有关(下面是完整日志):
W/bt-btif (18797): btif_gatt_set_encryption_cb() - Encryption failed (1)
我已经通过了确保将蓝牙事件发布到主线程上的处理程序的常规操作,现在我需要新的思路来尝试解决此问题。
我的日志捕获命令:
adb logcat | grep 'BLEService\|BluetoothGatt\|BtGatt\|bt\-'
日志输出:
D/BtGatt.GattService(18797): registerClient() - UUID=9a90904a-84e8-4f30-9b10-de78ac49f236
D/BtGatt.GattService(18797): onClientRegistered() - UUID=9a90904a-84e8-4f30-9b10-de78ac49f236, clientIf=5
D/BtGatt.GattService(18797): start scan with filters
D/BtGatt.ScanManager(18797): handling starting scan
D/BtGatt.GattService(18797): onScanFilterEnableDisabled() - clientIf=5, status=0, action=1
D/BtGatt.ScanManager(18797): callback done for clientIf - 5 status - 0
D/BtGatt.GattService(18797): onScanFilterParamsConfigured() - clientIf=5, status=0, action=0, availableSpace=15
D/BtGatt.ScanManager(18797): callback done for clientIf - 5 status - 0
D/BtGatt.ScanManager(18797): configureRegularScanParams() - queue=1
D/BtGatt.ScanManager(18797): configureRegularScanParams() - ScanSetting Scan mode=2 mLastConfiguredScanSetting=-2147483648
E/bt-btm (18797): Device already in IRK list
D/BtGatt.GattService(18797): stopScan() - queue size =1
D/BtGatt.GattService(18797): onScanFilterParamsConfigured() - clientIf=5, status=0, action=1, availableSpace=16
D/BtGatt.ScanManager(18797): callback done for clientIf - 5 status - 0
D/BtGatt.ScanManager(18797): stop scan
D/BtGatt.ScanManager(18797): configureRegularScanParams() - queue=0
D/BtGatt.ScanManager(18797): configureRegularScanParams() - ScanSetting Scan mode=-2147483648 mLastConfiguredScanSetting=2
D/BtGatt.ScanManager(18797): configureRegularScanParams() - queue emtpy, scan stopped
D/BtGatt.GattService(18797): unregisterClient() - clientIf=5
V/BLEService(21323): - connecting....
D/BluetoothGatt(21323): connect() - device: F4:B8:5E:51:A2:87, auto: false
D/BluetoothGatt(21323): registerApp()
D/BluetoothGatt(21323): registerApp() - UUID=4b8c32a4-4a74-49ff-a43f-a769c8200ab8
D/BtGatt.GattService(18797): registerClient() - UUID=4b8c32a4-4a74-49ff-a43f-a769c8200ab8
D/BtGatt.GattService(18797): onClientRegistered() - UUID=4b8c32a4-4a74-49ff-a43f-a769c8200ab8, clientIf=5
D/BluetoothGatt(21323): onClientRegistered() - status=0 clientIf=5
D/BtGatt.GattService(18797): clientConnect() - address=F4:B8:5E:51:A2:87, isDirect=true
E/bt-btm (18797): Device already in IRK list
W/bt-btm (18797): btm_acl_created hci_handle=4 link_role=0 transport=2
W/bt-btif (18797): info:x0
W/bt-l2cap(18797): L2CA_SetDesireRole() new:x1, disallow_switch:0
D/BtGatt.GattService(18797): client onConnected() - clientIf=5, connId=5, address=F4:B8:5E:51:A2:87
D/BluetoothGatt(21323): onClientConnectionState() - status=0 clientIf=5 device=F4:B8:5E:51:A2:87
V/BLEService(21323): Service have changed with old status: 0 and new status: 2
V/BLEService(21323): - discovering....
D/BluetoothGatt(21323): discoverServices() - device: F4:B8:5E:51:A2:87
D/BtGatt.GattService(18797): discoverServices() - address=F4:B8:5E:51:A2:87, connId=5
D/BtGatt.GattService(18797): onSearchCompleted() - connId=5, status=0
D/BluetoothGatt(21323): onSearchComplete() = Device=F4:B8:5E:51:A2:87 Status=0
V/BLEService(21323): Service have discovered with status: 0
V/BLEService(21323): - discovered....
D/BluetoothGatt(21323): setCharacteristicNotification() - uuid: f048abf6-3315-4d59-bad7-7e23ac18ee85 enable: true
D/BtGatt.GattService(18797): registerForNotification() - address=F4:B8:5E:51:A2:87 enable: true
D/BtGatt.GattService(18797): onRegisterForNotifications() - address=null, status=0, registered=1, charUuid=f048abf6-3315-4d59-bad7-7e23ac18ee85
I/BTConnectionReceiver(21037): onReceive(context, Intent { act=android.bluetooth.device.action.ACL_CONNECTED flg=0x4000010 cmp=com.google.android.googlequicksearchbox/com.google.android.search.core.service.BluetoothConnectionReceiver (has extras) }, [BluetoothDevice: address=F4:B8:5E:51:A2:87, alias=null, name=BLEDevice, majorDeviceClass=7936, deviceClass=7936]
I/BluetoothClassifier(21037): Bluetooth Device Name: BLEDevice
W/bt-btif (18797): btif_gatt_set_encryption_cb() - Encryption failed (1)
W/bt-smp (18797): io_cap = 4
W/bt-smp (18797): new io_cap = 4 p_cb->loc_enc_size = 16
E/bt-smp (18797): LTK ready
W/bt-smp (18797): smp_send_enc_info
W/bt-smp (18797): smp_send_id_info
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=2
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=2
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=16
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=16
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=16
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=2
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=2
E/bt-btif (18797): bta_dm_gatt_disc_result serivce_id len=16
W/bt-btif (18797): bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0008
W/bt-btif (18797): bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0008
W/bt-btif (18797): bta_gattc_conn_cback() - cif=5 connected=0 conn_id=5 reason=0x0008
E/bt-btm (18797): btm_sec_disconnected - Clearing Pending flag
如果有见识的人可以帮助我解决此问题,我将不胜感激。
1楼
BLE处理代码的重构揭示了一些错误处理的步骤,这使真正的问题蒙上了一层阴影。
处理每一步都正确允许onDescriptorWrite
回调的状态为调用BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION
这是由数表示。
收到状态BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION
时,您需要注册绑定事件,以便一旦绑定结束就可以重试,如下所示:
final IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
context.registerReceiver(receiver, filter);
接收器( BroadcastReceiver
子类)包含以下内容:
@Override
public void onReceive(Context context, Intent intent) {
final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
final int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
final int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
final String action = intent.getAction();
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action) && bondState == BluetoothDevice.BOND_BONDED) {
// retry
}
}