下篇問題
如何在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下圖
CHARACTERISTIC Android BLE ESP32 Descriptor
這裡還有一個陷阱,為什麼標1, 2 ,3 呢?
當我迴圈在抓CHARACTERISTIC時
先進入1. SERVICE
然後是2. Notify或 write CHARACTERISTIC
但是2.要選擇Notify 才能抓到 Client CHARACTERISTIC Config UUID 0X2902
如果2.是選 write CHARACTERISTIC,就怎麼都看不到 Client CHARACTERISTIC Config UUID
展示影片

參考文章
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
|