title: Kotlin callback not called within async function
body: <p>I am attempting to subscribe to multiple characteristics of a BLE peripheral within Android API 28. </p>
  
  <p>Due to the asynchronous nature of the BLE API I need to make the function that subscribes to each characteristic (<code>gatt.writeDescriptor()</code>) block; otherwise the BLE API will attempt to subscribe to multiple characteristics at once, despite the fact that only one descriptor can be written at a time: meaning that only one characteristic is ever subscribed to. </p>
  
  <p>The blocking is achieved by overriding the <code>onServicesDiscovered</code> callback and calling an asynchronous function to loop through and subscribe to characteristics. This is blocked with a simple Boolean value (<code>canContinue</code>). <strong>Unfortunately, the callback function <code>onDescriptorWrite</code> is <em>never</em> called.</strong></p>
  
  <p>See the code below: </p>
  
  <pre><code>override fun onDescriptorWrite(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) {
      canContinue = true 
  } 
  
  override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { 
      runBlocking {
          loopAsync(gatt)
      }
  }
  
  private suspend fun loopAsync(gatt: BluetoothGatt) {
      coroutineScope {
          async {
              gatt.services.forEach { gattService -&gt;                      
                  gattService.characteristics.forEach { gattChar -&gt;
                      CHAR_LIST.forEach {
                          if (gattChar.uuid.toString().contains(it)) {
                              canContinue = false
                              gatt.setCharacteristicNotification(gattChar, true)
  
                              val descriptor = gattChar.getDescriptor(UUID.fromString(BleNamesResolver.CLIENT_CHARACTERISTIC_CONFIG))                                     
                              descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
  
                              val write = Runnable {
                                  gatt.writeDescriptor(descriptor)
                              }
                              //private val mainHandler = Handler(Looper.getMainLooper())
                              //mainHandler.post(write)
                              //runOnUiThread(write)
                              gatt.writeDescriptor(descriptor)
  
                          }
  
                          while (!canContinue)
                      }
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>It was suggested in a <a href="https://stackoverflow.com/questions/52522448/make-function-block-in-kotlin/" title="related post">related post</a> that I run the <code>gatt.writeDescriptor()</code> function in the main thread. As you can see in the code above I have tried this to no avail using both <code>runOnUiThread()</code> and creating a Handler object following suggestions from <a href="https://stackoverflow.com/questions/11123621/running-code-in-main-thread-from-another-thread">this</a> question.</p>
  
  <p>The callback gets called if I call <code>gatt.writeDescriptor()</code> from a synchronous function, I have no idea why it doesn't get called from an asynchronous function. </p>
  
  <p>EDIT: It appears that the <code>while(!canContinue);</code> loop is actually blocking the callback. If I comment this line out, the callback triggers but then I face the same issue as before. How can I block this function?</p>
  
  <p>Any suggestions are most welcome! Forgive my ignorance, but I am very much used to working on embedded systems, Android is very much a new world to me!</p>
  
  <p>Thanks,
  Adam</p>