title: How to write large amount of text to write characteristic
body: <p>I am writing an Android application with Xamarin.Android, but an answer in native Android would be appreciated as well. In my Android application, I have a BLE Write Characteristic that devices can write to. It works, but I can't send more than 20 bytes, the rest gets cut off. My code to create and add the service/characteristic:</p>
  
  <pre><code>BluetoothGattService service = new BluetoothGattService(Java.Util.UUID.FromString(MyServiceUuid), GattServiceType.Primary);
  
  // write characteristic (write-only, supports subscriptions)
  BluetoothGattCharacteristic writeCharacteristic = new BluetoothGattCharacteristic(Java.Util.UUID.FromString(MyCharacteristicUuid), GattProperty.WriteNoResponse | GattProperty.Notify, GattPermission.Write);
  
  service.AddCharacteristic(writeCharacteristic);
  
  _bluetoothGattServer.AddService(service);
  </code></pre>
  
  <p>My code for on the side that writes to the characteristic:</p>
  
  <pre><code>public override void OnServicesDiscovered(BluetoothGatt gatt, [GeneratedEnum] GattStatus status)
  {
      base.OnServicesDiscovered(gatt, status);
  
      characteristic = gatt.GetService(Java.Util.UUID.FromString(MyServiceUuid))
                           .GetCharacteristic(Java.Util.UUID.FromString(MyCharacteristicUuid));
  
      if(characteristic.Properties.HasFlag(GattProperty.WriteNoResponse))
      {
          Log?.Invoke("writing characteristic...");
  
          characteristic.SetValue(MyVeryLongString);
          characteristic.WriteType = GattWriteType.NoResponse;
          gatt.WriteCharacteristic(characteristic);
      }
  }
  </code></pre>
  
  <p>And on the side that accepts the write request:</p>
  
  <pre><code>public override void OnCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, bool preparedWrite, bool responseNeeded, int offset, byte[] value)
  {
      base.OnCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
  
      Log?.Invoke("OnCharacteristicWriteRequest");
  
      string data = System.Text.Encoding.UTF8.GetString(value);
  
      Log?.Invoke(data);
  
      if(responseNeeded)
      {
          BluetoothGattServer.SendResponse(device, requestId, GattStatus.Success, 0, Encoding.ASCII.GetBytes("ok"));
      }
  }
  </code></pre>
  
  <p>I see there is an <code>offset</code>, but this function only gets called once. I must be missing something on one side?</p>
  
  <p>The funny thing is, that when I test this Android application with the iOS version of my application, I do not have this issue. I only have this issue when both devices are Androids.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>My new implementation of <code>OnCharacteristicWriteRequest</code>:</p>
  
  <pre><code>public override void OnCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, bool preparedWrite, bool responseNeeded, int offset, byte[] value)
  {
      base.OnCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
  
      Log?.Invoke("OnCharacteristicWriteRequest");
  
      string data = System.Text.Encoding.UTF8.GetString(value);
  
      Log?.Invoke(data);
  
      Guid characteristicId = new Guid(characteristic.Uuid.ToString());
      var record = _writeCharacteristicsReceived.FirstOrDefault(c =&gt; c.DeviceAddress == device.Address &amp;&amp; c.CharacteristicId == characteristicId);
  
      if(record != null)
      {
          record.Data += data;
      }
      else
      {
          record = new CharacteristicWriteReceived()
          {
              CharacteristicId = characteristicId,
              DeviceAddress = device.Address,
              Data = data
          };
  
          _writeCharacteristicsReceived.Add(record);
      }
  
      if (record?.Data.EndsWith(Constants.WriteCharacteristicEndDelimiter) == true)
      {
          _writeCharacteristicsReceived.Remove(record);
          record.Data = record.Data.Substring(0, record.Data.Length - Constants.WriteCharacteristicEndDelimiter.Length); // remove the end delimeter
          Log?.Invoke(record.Data);
  
          OnCharacteristicWriteReceived?.Invoke(record);
      }
  
      if (responseNeeded)
      {
          BluetoothGattServer.SendResponse(device, requestId, GattStatus.Success, offset, value);
      }
  }
  </code></pre>