title: How to enable multiple BLE characteristic notifications on Xamarin/Android?
body: <p>I am trying to enable notifications for more than one BLE characteristic using Xamarin/Android but seem unable to do so.  The app seems to stop receiving any BLE events if I try and enable more than one at a time.</p>
  
  <p>Can anyone confirm whether this is possible using Tamarin/Android.  We have a native iOS app that works just fine with multiple notifications enabled.  The basic steps we use are as follows:</p>
  
  <ol>
  <li>Scan for device</li>
  <li>Connect to device</li>
  <li>Discover services</li>
  <li>For each discovered service iterate through characteristics and enable the ones that are required</li>
  <li>Process each asynchronous callback event in the BLE callback</li>
  </ol>
  
  <p>Any time we try and enable notifications on more than one characteristic we no longer receive any events.</p>
  
  <p>I have also been unable to find any examples where more than one characteristic is being enabled.</p>
  
  <p>I hope I have simply missed something fundamental about using the Xamarin/Android APIs here.</p>
  
  
  
  <pre class="lang-cs prettyprint-override"><code>public override void OnServicesDiscovered (BluetoothGatt gatt, GattStatus status)
  {
      base.OnServicesDiscovered (gatt, status);
      foreach (BluetoothGattService service in gatt.Services) {
          string uuid = service.Uuid.ToString ().ToUpper();
          if (uuid.Equals (BLEServices.HRService.ToUpper())) {
              _Adap.LogMessage ("HRService discovered");
              foreach(BluetoothGattCharacteristic characteristic in service.Characteristics) {
                  string c_uuid = characteristic.Uuid.ToString ().ToUpper ();
                  _Adap.LogMessage (" HRCharacteristic: " + c_uuid);
  
                  if (c_uuid.Equals(_Adap.useCharacteristic.ToUpper())) {
                      _Adap.LogMessage ("  enabling HRCharacteristic");
                      gatt.SetCharacteristicNotification(characteristic, true);
                      BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor (Java.Util.UUID.FromString (BLEServices.CLIENT_CHARACTERISTIC_CONFIG), GattDescriptorPermission.Write | GattDescriptorPermission.Read);
                      characteristic.AddDescriptor (descriptor);
                      descriptor.SetValue (BluetoothGattDescriptor.EnableNotificationValue.ToArray ());
                      gatt.WriteDescriptor (descriptor);
                      _Adap.StartTimer ();
                  }
              }
  
          } else if (uuid.Equals (BLEServices.BatteryService.ToUpper())) {
              _Adap.LogMessage ("BatteryService discovered");
              foreach (BluetoothGattCharacteristic characteristic in service.Characteristics) {
                  string c_uuid = characteristic.Uuid.ToString ().ToUpper ();
                  _Adap.LogMessage (" BatteryService: " + c_uuid);
  
                  if (c_uuid.Equals (_Adap.useCharacteristic.ToUpper ())) {
                      _Adap.LogMessage ("  reading batteryCharacteristic");
                      // This may only be reported when the battery level changes so get the level first by doing a read
                      gatt.ReadCharacteristic (characteristic);
  
                      //gatt.SetCharacteristicNotification (characteristic, true);
                      //BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor (Java.Util.UUID.FromString (BLEServices.CLIENT_CHARACTERISTIC_CONFIG), GattDescriptorPermission.Write | GattDescriptorPermission.Read);
                      //characteristic.AddDescriptor (descriptor);
                      //descriptor.SetValue (BluetoothGattDescriptor.EnableNotificationValue.ToArray ());
                      //gatt.WriteDescriptor (descriptor);
                  }
              }
          } else if (uuid.Equals (BLEServices.DeviceInfoService.ToUpper())) {
              _Adap.LogMessage ("DeviceInfoService discovered");
              foreach (BluetoothGattCharacteristic characteristic in service.Characteristics) {
                  string c_uuid = characteristic.Uuid.ToString ().ToUpper ();
                  _Adap.LogMessage (" DeviceInfoService: " + c_uuid);
                  if (c_uuid.Equals (BLEServices.kModelNumberCharacteristicUuidString.ToUpper ())) {
                      //gatt.ReadCharacteristic (characteristic);
                  }
              }
          } else if (uuid.Equals (BLEServices.kHxM2CustomServiceUuidString.ToUpper())) {
              _Adap.LogMessage ("HxM2CustomService discovered");
              foreach (BluetoothGattCharacteristic characteristic in service.Characteristics) {
                  string c_uuid = characteristic.Uuid.ToString ().ToUpper ();
                  _Adap.LogMessage (" HxM2CustomCharacteristic: " + c_uuid);
  
                  if (c_uuid.Equals (_Adap.useCharacteristic.ToUpper ())) {
                      _Adap.LogMessage ("  enabling HxM2 characteristic: "+_Adap.useCharacteristic);
                      gatt.SetCharacteristicNotification (characteristic, true);
                      BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor (Java.Util.UUID.FromString (BLEServices.CLIENT_CHARACTERISTIC_CONFIG), GattDescriptorPermission.Write | GattDescriptorPermission.Read);
                      characteristic.AddDescriptor (descriptor);
                      descriptor.SetValue (BluetoothGattDescriptor.EnableNotificationValue.ToArray ());
                      gatt.WriteDescriptor (descriptor);
                      // Start a timer to make sure that we can recover if we never receive any data from the device
                      _Adap.StartTimer ();
                  }
  
              }
          } else {
              _Adap.LogMessage ("Unknown Service "+uuid+" discovered");
          }
      }
  }
  </code></pre>
  
  <p>Can anyone explain what the following lines are for </p>
  
  <pre class="lang-cs prettyprint-override"><code>BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor (Java.Util.UUID.FromString (BLEServices.CLIENT_CHARACTERISTIC_CONFIG), GattDescriptorPermission.Write | GattDescriptorPermission.Read);
  characteristic.AddDescriptor (descriptor);
  descriptor.SetValue (BluetoothGattDescriptor.EnableNotificationValue.ToArray ());
  gatt.WriteDescriptor (descriptor);
  </code></pre>