woff 發表於 2020-4-23 11:39:39

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]
查看完整版本: Android BLE ESP32的onCharacteristicChanged沒有回撥及getDescriptor null