Android BLE中心裝置的onCharacteristicChanged()方法沒有回撥
阿新 • • 發佈:2019-01-25
描述:當裝置為 Indication 模式時,裝置的值有變化時會主動返回給App,App在 onCharacteristicChanged() 方法中能收到返回的值。
Indication: 從機會先向主機發送一條通知,主機接收到通知後去讀取從機資料
Notification:從機直接傳送給主機資料
問題:在App中通過如下程式碼註冊監聽,註冊成功後就能接收到裝置主動反饋的值了。然而以下程式碼執行後依舊收不到反饋。但是對裝置的讀寫都是可行的,並且iOS端可以接收到通知。
bluetoothGatt.setCharacteristicNotification(characteristic, true)
解決: 當上面的方法執行返回true後,還要執行如下的程式碼才能註冊成功。
for(BluetoothGattDescriptor dp: characteristic.getDescriptors()){ if (dp != null) { if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) { dp.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); } else if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) { dp.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); } gatt.writeDescriptor(dp); } }
完整的程式碼如下:
public boolean enableNotification(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID) { boolean success = false; BluetoothGattService service = gatt.getService(serviceUUID); if (service != null) { BluetoothGattCharacteristic characteristic = findNotifyCharacteristic(service, characteristicUUID); if (characteristic != null) { success = gatt.setCharacteristicNotification(characteristic, true); if (success) { // 來源:http://stackoverflow.com/questions/38045294/oncharacteristicchanged-not-called-with-ble for(BluetoothGattDescriptor dp: characteristic.getDescriptors()){ if (dp != null) { if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) { dp.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); } else if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) { dp.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); } gatt.writeDescriptor(dp); } } } } } return success; } private BluetoothGattCharacteristic findNotifyCharacteristic(BluetoothGattService service, UUID characteristicUUID) { BluetoothGattCharacteristic characteristic = null; List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics(); for (BluetoothGattCharacteristic c : characteristics) { if ((c.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0 && characteristicUUID.equals(c.getUuid())) { characteristic = c; break; } } if (characteristic != null) return characteristic; for (BluetoothGattCharacteristic c : characteristics) { if ((c.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0 && characteristicUUID.equals(c.getUuid())) { characteristic = c; break; } } return characteristic; }