Android BLE ESP32的onCharacteristicChanged沒有回撥及getDescriptor null
下篇問題如何在Android BLE 發送數據 ESP32 ?
如何在Android BLE 發送到 ESP32 超過20個字元的數據?
描述:當裝置為 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);
}
}
在BluetoothLeService.java加入完整程式碼如下:
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) {
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;
}
舉例來說,如ESP32下圖
這裡還有一個陷阱,為什麼標1, 2 ,3 呢?
當我迴圈在抓CHARACTERISTIC時
先進入1. SERVICE
然後是2. Notify或 write CHARACTERISTIC
但是2.要選擇Notify 才能抓到 Client CHARACTERISTIC Config UUID 0X2902
如果2.是選 write CHARACTERISTIC,就怎麼都看不到 Client CHARACTERISTIC Config UUID
展示影片
GI9lP48cCjw
參考文章
https://www.itread01.com/content/1548417271.htmlhttps://stackoverflow.com/questions/58998064/android-bluedroid-ble-certain-phones-arent-receiving-notifications-from-gatt-s
來源
http://www.netyea.com
頁:
[1]