title: How to know if BLE indicate was acknowledged in Android
body: <p>We are working on a Bluetooth Low Energy communication between two Android apps. One is the peripheral/server one the central/client.
  The server will send an indicate to the clients if the data has changed. However, we didn't find a way to make sure that the data was actually acknowledged on the client side. 
  How can we figure out, if the client received and acknowledged the data in order to react accordingly on the server side to it?</p>
  
  <p>According to Android documentation there is the callback onNotificationSent for the BleutoothGattServer. 
  <a href="https://developer.android.com/reference/android/bluetooth/BluetoothGattServerCallback#onNotificationSent(android.bluetooth.BluetoothDevice,%20int)" rel="nofollow noreferrer">https://developer.android.com/reference/android/bluetooth/BluetoothGattServerCallback#onNotificationSent(android.bluetooth.BluetoothDevice,%20int)</a></p>
  
  <p>However by debugging and doing some tests it seems this method really is just called if the notification is sent. There is no guarantee the message was actually received nor acknowledged. </p>
  
  <p>So here is how we setup the characteristics for the GattServer</p>
  
  <pre><code>BluetoothGattService service = new BluetoothGattService(SERVICE_LOGIN_UUID,
                  BluetoothGattService.SERVICE_TYPE_PRIMARY);
  
          // Write characteristic
          BluetoothGattCharacteristic writeCharacteristic = new BluetoothGattCharacteristic(CHARACTERISTIC_LOGIN_UUID,
                  BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_READ| BluetoothGattCharacteristic.PROPERTY_INDICATE,
                  // Somehow this is not necessary, the client can still enable notifications
  //                        | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                  BluetoothGattCharacteristic.PERMISSION_WRITE | BluetoothGattCharacteristic.PERMISSION_READ);
  
          service.addCharacteristic(writeCharacteristic);
  
          mGattServer.addService(service);
  </code></pre>
  
  <p>and then we notify the clients by calling this</p>
  
  <pre><code>mHandler.post(() -&gt; {
              BluetoothGattService service = mGattServer.getService(SERVICE_LOGIN_UUID);
              BluetoothGattCharacteristic characteristic = service.getCharacteristic(uuid);
              log("Notifying characteristic " + characteristic.getUuid().toString()
                      + ", new value: " + StringUtils.byteArrayInHexFormat(value));
  
              characteristic.setValue(value);
              boolean confirm = BluetoothUtils.requiresConfirmation(characteristic);
              for(BluetoothDevice device : mDevices) {
                  mGattServer.notifyCharacteristicChanged(device, characteristic, confirm);
              }
          });
  </code></pre>
  
  <p>*PLEASE IGNORE THE FOR LOOP HERE FOR THE MOMENT</p>
  
  <p>This will cause onNotificationSent to be called but doesn't help to know if it was acknowledged or not. </p>
  
  <p>Let me know if you need other code parts.</p>
  
  <p>Thank you all already, many greetings</p>