title: BluetoothGatt.writeCharacteristic() success for the first time but return false after
body: <p>i'am building a Android application that read data from some BLE devices, the process of the application start by :</p>
  
  <ul>
  <li>Discover the devices.</li>
  <li>check if they are paired, if not paird them.</li>
  <li>connect to the first devices then read data of this devices, then stop and 
  stay connected (if the first time that i want to connect to the device, i 
  call <code>connectGatt()</code>, else if already connected call 
  <code>gatt.discoverServices()</code> )</li>
  <li>switch to second devices (connect + read + write + stop reading)</li>
  <li><p>when i acheive the last device, i stop the process for a while, and i reapet 
  the process from the begining </p>
  
  <p>All the process work fine the first time for all devices, but when  the 
  process go back  to the first device and i call <code>gatt.discoverServices()</code> , 
  instead of <code>connectGatt()</code>, i get all the Services and also the Characteristics 
  but my <code>gatt.writeCharacteristic()</code> fail and return false.</p>
  
  <p>can anyone help to know why it fails and how o fix this issue.</p>
  
  <p>this is how my code look like</p>
  
  <pre><code> if (DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt() == null) {
            // if(true){
            log4jfile.info(" BluetoothGATT = null :  call connectGatt");
            BluetoothService.reading_device = device.getAddress();
  
            bluetoothGatt = device.connectGatt(this, false, bluetoothGattCallback)
  
            if (DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt() == null) {
                  DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).setBluetoothGatt(bluetoothGatt);
            }
      } else {
  
            if (mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT).contains(device)) {
                  log4jfile.info(" BluetoothGATT != null :  call discoverServices");
  
                  DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt().discoverServices();
            } else {
                  log4jfile.info(" BluetoothGATT != null :  call connect");
                  DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt().connect();
            }
  
      }
  </code></pre></li>
  </ul>
  
  <p>Note:</p>
  
  <ul>
  <li><p>i don't  call <code>connectGatt()</code> many time for the same device because the number 
  of BluetoothGatt that we could create in android is 32.</p></li>
  <li><p>i d'on't call <code>bluetoothGatt.close()</code> after i finish cause i want stay 
  connected to my devices all the time.</p></li>
  </ul>
  
  <p><strong>EDIT</strong></p>
  
  <pre><code>bluetoothGatt = device.connectGatt(this, false, new BluetoothGattCallback() {
      @Override
      public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
  
            log4jfile.info("onConnectionStateChange, status : " + status + " parseConnection : " + GattStatusParse.parseConnection(status) + "  or " + GattStatusParse.parseConnection(status));
            DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).setSuccess_Counter(DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getSuccess_Counter() + 1);
            isConnected = BluetoothProfile.STATE_CONNECTED == newState;
            if (status == BluetoothGatt.GATT_SUCCESS) {
                  for (BluetoothDeviceWrapper blw : DeviceListAdapter.devices) {
                        if (blw.getDevice().getAddress().equals(device.getAddress())) {
                              blw.setConnectionFailed(false);
                        }
                  }
                  if (isConnected) {
                        log4jfile.info(" GATT connected " + device.getAddress() + " state of the opération : " + status + " connexion state : " + newState);
                        if (!connectedBluethoothDevice.contains(device)) {
                              connectedBluethoothDevice.add(device);
                        }
                        Log.i(TAG, "GATT connected." + connectedBluethoothDevice.toString());
  
                        gatt.discoverServices();
                        //LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
                        BluetoothService.reading_device = device.getAddress();
                        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
                  } else {
                        log4jfile.info(" GATT disconnected " + device.getAddress() + " state of the opération : " + status + " connexion state : " + newState);
                        if (connectedBluethoothDevice.contains(device)) {
                              connectedBluethoothDevice.remove(device);
                        }
                        Log.i(TAG, "GATT disconnected." + connectedBluethoothDevice.toString());
                        //NotificationService_.intent(BluetoothService.this).stop();
                        notificationManager.notify(442, getNotification(device));
                        BluetoothService.reading_device = "";
                        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
  
                  }
            } else {
  
                  if (connectedBluethoothDevice.contains(device)) {
                        // mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
                        int mConnectionState = mBluetoothManager.getConnectionState(device, BluetoothProfile.GATT);
                        if (mConnectionState == BluetoothProfile.STATE_DISCONNECTED || mConnectionState == BluetoothProfile.STATE_DISCONNECTING) {
                              connectedBluethoothDevice.remove(device);
                        }
                  }
  
                  for (BluetoothDeviceWrapper blw : DeviceListAdapter.devices) {
                        if (blw.getDevice().getAddress().equals(device.getAddress())) {
                              blw.setConnectionFailed(true);
                        }
                  }
                  LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
  
                  BluetoothService.FAILED_CONNECTION = BluetoothService.FAILED_CONNECTION + 1;
                  DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).setFail_Counter(DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getFail_Counter() + 1);
                  log4jfile.info("connection _ Failed : " + BluetoothService.FAILED_CONNECTION);
                  if (1 &lt;= BluetoothService.FAILED_CONNECTION &amp;&amp; BluetoothService.FAILED_CONNECTION &lt; Integer.parseInt(NombreDeTentativeDeConnexion)) {
                        if (MainActivity.current == 0) {
                              MainActivity.current = DeviceListAdapter.devicesFounder.size() - 1;
                        } else {
                              MainActivity.current = MainActivity.current - 1;
                        }
  
                        if (!MainActivity.stoppedServices) {
                              Log.e(TAG, "sendBroadcast DEVICE_READ_DONE 2");
                              final Intent myIntent = new Intent(DEVICE_READ_DONE);
                              sendBroadcast(myIntent);
                              stopSelf();
                        }
  
                  } else {
                        BluetoothService.FAILED_CONNECTION = 0;
                        if (!MainActivity.stoppedServices) {
                              Log.e(TAG, "sendBroadcast DEVICE_READ_DONE 3");
                              final Intent myIntent = new Intent(DEVICE_READ_DONE);
                              sendBroadcast(myIntent);
                              stopSelf();
                        }
                  }
            }
  
      }
  
      @Override
      public void onServicesDiscovered(BluetoothGatt gatt, int status) {
  
            startForeground(442, getNotification(device));
            log4jfile.info("Services discovered. status : " + status + " , parse status : " + GattStatusParse.parse(status));
            BluetoothService.reading_device = gatt.getDevice().getAddress();
            LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
            if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
                  log4jfile.info("GATT_INSUFFICIENT_AUTHENTICATION");
                  handleAuthenticationError(gatt);
                  return;
            }
  
            discoverCharacteristics(gatt);
      }
  
      @Override
      public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            System.gc();
            log4jfile.info("Characteristic written, status: " + status + " , parse status : " + GattStatusParse.parse(status));
            //BluetoothService.reading_device=gatt.getDevice().getAddress();
            if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
                  log4jfile.error("GATT_INSUFFICIENT_AUTHENTICATION");
                  handleAuthenticationError(gatt);
                  return;
            }
  
            final byte command = characteristic.getValue()[0];
            switch (command) {
                  case WRITE_TIME:
                        log4jfile.info("Time written.");
                        final BluetoothGattCharacteristic batteryCharacteristic = readableCharacteristics.get(Characteristic.BATTERY.getUuid());
                        gatt.setCharacteristicNotification(batteryCharacteristic, true);
                        for (BluetoothGattDescriptor descriptor : batteryCharacteristic.getDescriptors()) {
                              if (descriptor.getUuid().toString().startsWith("00002904")) {
                                    descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                                    gatt.writeDescriptor(descriptor);
                              }
                        }
                        break;
                  case WRITE_NOTIFICATION:
                        log4jfile.info("Notification sent.");
                        if (notificationsQueue.isEmpty()) {
                              log4jfile.info("Reading characteristics...");
                              //BluetoothService.reading_device=gatt.getDevice().getAddress();
                              readNextCharacteristics(gatt);
                        } else {
                              log4jfile.info("writing next notification...");
                              alertIn.setValue(notificationsQueue.poll());
                              gatt.writeCharacteristic(alertIn);
                        }
                        break;
                  default:
                        log4jfile.info("No such ALERT IN command: " + command);
                        break;
            }
      }
  
      @Override
      public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            log4jfile.info("onDescriptorWrite write, status: " + status + " , parse status : " + GattStatusParse.parse(status));
            readCharacteristic(gatt, Characteristic.MANUFACTURER);
      }
  
      @Override
      public void onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic gattCharacteristic, int status) {
            log4jfile.info("onCharacteristicRead, device : " + gatt.getDevice().getAddress() + " status : " + status + " , parse status : " + GattStatusParse.parse(status));
            System.gc();
            if (!MainActivity.stoppedServices &amp;&amp; gatt.getDevice().getAddress().equals(BluetoothService.reading_device)) {
                  if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
                        handleAuthenticationError(gatt);
                        return;
                  }
  
                  final String characteristicUuid = gattCharacteristic.getUuid().toString();
                  final Characteristic characteristic = Characteristic.byUuid(characteristicUuid);
                  switch (characteristic) {
                        case MANUFACTURER:
                              manufacturerInfo.manufacturer = gattCharacteristic.getStringValue(0);
                              readCharacteristic(gatt, Characteristic.FW_REVISION);
                              break;
                        case FW_REVISION:
                              manufacturerInfo.firmwareRevision = gattCharacteristic.getStringValue(0);
                              readCharacteristic(gatt, Characteristic.MODE);
                              break;
                        default:
                              //BluetoothService.reading_device=gatt.getDevice().getAddress();
                              //LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
                              log4jfile.info("Characteristic read: " + characteristic.name() + " device " + gatt.getDevice().getAddress() + " basculeTimer :" + BluetoothService.basculeTimer);
                              if (1 &gt; BluetoothService.FAILED_CONNECTION || BluetoothService.FAILED_CONNECTION &gt;= 3) {
                                    BluetoothService.FAILED_CONNECTION = 0;
                              }
                              BluetoothService.basculeTimer++;
                              if (BluetoothService.basculeTimer == 0 || BluetoothService.basculeTimer == 10) {
                                    // BluetoothService.reading_device=gatt.getDevice().getAddress();
                                    LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
                              }
                              if (!gatt.getDevice().getAddress().equals(BluetoothService.reading_device)) {
                                    // BluetoothService.reading_device = bluetoothGatt.getDevice().getAddress();
                                    LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
                              }
                              //BluetoothService.reading_device=gatt.getDevice().getAddress();
  
                              if (characteristic == Characteristic.MODE) {
                                    final Mode newMode = Mode.bySymbol(gattCharacteristic.getValue()[0]);
                                    log4jfile.info("mode change : " + newMode.name());
                                    if (mode != newMode) {
                                          onModeChanged(newMode);
                                    }
                              } else {
                                    onBluetoothDataReceived(characteristic, gattCharacteristic.getValue());
                              }
  
  //                                                if (shouldUpdateTime) {
  //                                                      updateTime(gatt.getDevice());
  //                                                }
  
                              if (notificationsQueue.isEmpty()) {
                                    log4jfile.info(" notificationsQueue isEmpty ==&gt; readNextCharacteristics");
                                    readNextCharacteristics(gatt);
                              } else {
                                    log4jfile.info(" notificationsQueue NotisEmpty ==&gt; writeCharacteristic");
                                    alertIn.setValue(notificationsQueue.poll());
                                    gatt.writeCharacteristic(alertIn);
                              }
  
                              break;
                  }
            }
      }
  
      @Override
      public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic gattCharacteristic) {
            System.gc();
            final String characteristicUuid = gattCharacteristic.getUuid().toString();
            final Characteristic characteristic = Characteristic.byUuid(characteristicUuid);
            log4jfile.info("Characteristic changed: " + characteristic.name());
  
            if (characteristic == Characteristic.BATTERY) {
                  onBluetoothDataReceived(Characteristic.BATTERY, gattCharacteristic.getValue());
            }
      }
  });
  
  
  private void discoverCharacteristics(final BluetoothGatt gatt) {
      log4jfile.info("discoverCharacteristics. services length : " + gatt.getServices().size());
      //BluetoothService.reading_device = gatt.getDevice().getAddress();
      LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.REFRESH_ADAPTER));
      if (gatt.getServices().size() == 0) {
            log4jfile.info("No services found.");
            //LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(BluetoothService.DEVICE_READ_DONE));
      }
  
      for (BluetoothGattService gattService : gatt.getServices()) {
            if(gatt.getDevice().getAddress().equals(BluetoothService.reading_device)){
                   storeCharacteristicsFromService(gattService,gatt.getDevice());
  
            }
      }
  }
  
  private void storeCharacteristicsFromService(BluetoothGattService gattService,BluetoothDevice device) {
      log4jfile.info("storeCharacteristicsFromService , length : " + gattService.getCharacteristics().size());
      for (BluetoothGattCharacteristic gattCharacteristic : gattService.getCharacteristics()) {
            final String characteristicUuid = gattCharacteristic.getUuid().toString();
            final Characteristic characteristic = Characteristic.byUuid(characteristicUuid);
  
            if (characteristic == Characteristic.ALERT_IN) {
                  log4jfile.info( "ALERT_IN DISCOVERED");
                  DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).setAlertIn(null);
                  DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).setAlertIn(gattCharacteristic);
  
                  alertIn = gattCharacteristic;
                  setTime();
                  if(device.getAddress().equals(BluetoothService.reading_device)) {
                        updateTime(device);
                  }
                  NotificationService_.intent(BluetoothService.this).start();
            } else if (characteristic != null) {
                  log4jfile.info("characteristic " + characteristic);
                  log4jfile.info(characteristic.getType() + ": " + characteristic.name());
                  readableCharacteristics.put(characteristicUuid, gattCharacteristic);
            } else {
                  log4jfile.info("UNKNOWN: " + characteristicUuid);
            }
      }
  }
  
  
  public void setTime() {
      Log.d(TAG, "Setting time...");
      if (!isConnected || alertIn == null) {
            Log.w(TAG, "Time not set.");
            return;
      }
  
      shouldUpdateTime = true;
  }
  
  void updateTime(BluetoothDevice device) {
      log4jfile.info("updateTime ..."+device.getAddress());
      shouldUpdateTime = false;
  
      final byte[] time = new byte[20];
      final long currentTime = System.currentTimeMillis();
      final long currentTimeWithTimeZoneOffset = (currentTime + TimeZone.getDefault().getOffset(currentTime)) / 1000;
  
      final ByteBuffer buffer = ByteBuffer.allocate(8);
      buffer.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().put(currentTimeWithTimeZoneOffset);
      final byte[] utcBytes = buffer.array();
  
      final byte length = 0x04;
  
      time[0] = WRITE_TIME;
      time[1] = length;
      time[2] = utcBytes[0];
      time[3] = utcBytes[1];
      time[4] = utcBytes[2];
      time[5] = utcBytes[3];
      Boolean result=false;
      DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getAlertIn().setValue(time);
      DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getAlertIn().setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
      log4jfile.info(DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt().getDevice().getAddress());
      while (!result){
             result=DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getBluetoothGatt().writeCharacteristic(DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getAlertIn());
             log4jfile.info("write return "+result+" alertIn :"+DeviceListAdapter.devicesState.getDeviceState(device.getAddress()).getAlertIn().getStringValue(0));
            try {
                  Thread.sleep(1000);
            } catch (InterruptedException e) {
                  e.printStackTrace();
            }
      }
  }
  </code></pre>