title: How to read characteristic from BLE device until it have results?
body: <p>I'm building an app that should to connect with a BLE device.
  This device, storage the information that retreive from its sensors in a queque.</p>
  
  <p>It is possibile that at the time X, the queque of this device have 100 items value.</p>
  
  <p>Now my Android application must to connect of it, and download the data of the characteristic untile the queque of devis is empty.</p>
  
  <p>This is the code that I use to read one value at time. How can I change it to get all data ?</p>
  
  <pre><code>    @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_ble);
          mHandler = new Handler();
  
          //mSensors = db.getAllSensorTypes();
          //BLUETOOTH LOW ENERGY NON SUPPORTATO
          if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
              Toast.makeText(this, "BLE Not Supported",
                      Toast.LENGTH_SHORT).show();
              finish();
          }
          final BluetoothManager bluetoothManager =
                  (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
          mBluetoothAdapter = bluetoothManager.getAdapter();
          //VERIFICO SE IL BLUETOOTH DEL DISPOSITIVO E' ABILITATO
          //OPPURE NO. SE NON è ABILITATO DEVO CHIEDERE ALL'UTENTE DI ATTIVARLO
          // Ensures Bluetooth is available on the device and it is enabled. If not,
          if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
              Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
              startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
          }
  
          tvBLE = (TextView) findViewById(R.id.tvBLE);
          ibDownload = (ImageButton) findViewById(R.id.ibDownload);
  
          //ibDownload.setEnabled(false);
  
          ibDownload.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  if(currDevice!=null){
                      GattClientCallback gattClientCallback = new GattClientCallback();
                      mGatt = currDevice.connectGatt(getBaseContext(), false, gattClientCallback);
                      scanLeDevice(false);// will stop after first device detection
                  }
                  refreshListView();
              }
          });
  
          // Bluetooth is supported?
          if (mBluetoothAdapter == null) {
              Toast.makeText(this, "Bluetooth non supportato", Toast.LENGTH_SHORT).show();
              finish();
          }
  
      }
  
      private void scanLeDevice(final boolean enable) {
          if (enable) {
              mHandler.postDelayed(new Runnable() {
                  @Override
                  public void run() {
                      if (Build.VERSION.SDK_INT &lt; 21) {
                          mBluetoothAdapter.stopLeScan(mLeScanCallback);
                      } else {
                          mLEScanner.stopScan(mScanCallback);
  
                      }
                  }
              }, SCAN_PERIOD);
              if (Build.VERSION.SDK_INT &lt; 21) {
                  mBluetoothAdapter.startLeScan(mLeScanCallback);
              } else {
                  mLEScanner.startScan(filters, settings, mScanCallback);
              }
          } else {
              if (Build.VERSION.SDK_INT &lt; 21) {
                  mBluetoothAdapter.stopLeScan(mLeScanCallback);
              } else {
                  mLEScanner.stopScan(mScanCallback);
              }
          }
      }
  
  
      private ScanCallback mScanCallback = new ScanCallback() {
          @Override
          public void onScanResult(int callbackType, ScanResult result) {
              Log.i("callbackType", String.valueOf(callbackType));
              Log.i("result", result.toString());
              BluetoothDevice btDevice = result.getDevice();
              connectToDevice(btDevice);
          }
  
          @Override
          public void onBatchScanResults(List&lt;ScanResult&gt; results) {
              for (ScanResult sr : results) {
                  Log.i("ScanResult - Results", sr.toString());
              }
          }
  
          @Override
          public void onScanFailed(int errorCode) {
              Log.e("Scan Failed", "Error Code: " + errorCode);
          }
      };
  
      private BluetoothAdapter.LeScanCallback mLeScanCallback =
              new BluetoothAdapter.LeScanCallback() {
                  @Override
                  public void onLeScan(final BluetoothDevice device, int rssi,
                                       byte[] scanRecord) {
                      runOnUiThread(new Runnable() {
                          @Override
                          public void run() {
                              Log.i("onLeScan", device.toString());
                              connectToDevice(device);
                          }
                      });
                  }
              };
  
      public void connectToDevice(BluetoothDevice device) {
          String nomeDispositivo = device.getName();
          if (mGatt == null &amp;&amp; device.getName()!= null &amp;&amp; device.getName().equals("Diabesity care")) {
              currDevice = device;
              ibDownload.setEnabled(true);
              ibDownload.setImageResource(R.drawable.download_ok);
              //mGatt = device.connectGatt(this, false, gattCallback);
              //scanLeDevice(false);// will stop after first device detection
          }
      }
  
  
  
      private class GattClientCallback extends BluetoothGattCallback {
  
          @Override
          public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
              super.onConnectionStateChange(gatt, status, newState);
              Log.i("tag","onConnectionStateChange newState: " + newState);
  
              if (status == BluetoothGatt.GATT_FAILURE) {
                  logError("Connection Gatt failure status " + status);
                  disconnectGattServer();
                  return;
              } else if (status != BluetoothGatt.GATT_SUCCESS) {
                  // handle anything not SUCCESS as failure
                  logError("Connection not GATT sucess status " + status);
                  disconnectGattServer();
                  return;
              }
  
              if (newState == BluetoothProfile.STATE_CONNECTED) {
                  Log.i("INFO","Connected to device " + gatt.getDevice().getAddress());
                  setConnected(true);
                  gatt.discoverServices();
              } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                  Log.i("INFO","Disconnected from device");
                  disconnectGattServer();
              }
          }
  
          @Override
          public void onServicesDiscovered(BluetoothGatt gatt, int status) {
              super.onServicesDiscovered(gatt, status);
  
              if (status != BluetoothGatt.GATT_SUCCESS) {
                  Log.i("INFO","Device service discovery unsuccessful, status " + status);
                  return;
              }
  
              List&lt;BluetoothGattCharacteristic&gt; matchingCharacteristics = BluetoothUtils.findCharacteristics(gatt);
              if (matchingCharacteristics.isEmpty()) {
                  logError("Unable to find characteristics.");
                  return;
              }
  
  
              ReadQueue = new ArrayList&lt;&gt;();
              for (BluetoothGattCharacteristic characterist:  matchingCharacteristics) {
                  ReadQueue.add(characterist);
              }
              ReadQueueIndex = 1;
              ReadCharacteristics(ReadQueueIndex);
  
  
          }
  
          private void ReadCharacteristics(int index){
              mGatt.readCharacteristic(ReadQueue.get(index));
          }
  
          @Override
          public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
              super.onCharacteristicRead(gatt, characteristic, status);
              if (status == BluetoothGatt.GATT_SUCCESS) {
                  Log.i("INFO","Characteristic read successfully");
                  //readCharacteristic(characteristic);
  
                  SensorData mSenData = new SensorData();
                  mSenData.setValue(characteristic.getStringValue(0));
                  //TO-DO HO COMMENTATO QUESTA RIGA DI CODICE
                  // mSenData.setIdType(st.getId());
                  mSenData.setIdType(++id);
                  mSenData.setCharacteristic(characteristic.getUuid().toString());
                  mSenData.setValueTimestamp(db.getDateTime());
                  //inserisco i dati nel db
                  db.insertSensorData(mSenData);
  
  
                  ReadQueue.remove(ReadQueue.get(ReadQueueIndex));
                  if (ReadQueue.size() &gt;= 0) {
                      ReadQueueIndex--;
                      if (ReadQueueIndex == -1) {
                          Log.i("Read Queue: ", "Complete");
                      }
                      else {
                          ReadCharacteristics(ReadQueueIndex);
                      }
                  }
                  //refreshListView();
  
              } else {
                  logError("Characteristic read unsuccessful, status: " + status);
                  // Trying to read from the Time Characteristic? It doesnt have the property or permissions
                  // set to allow this. Normally this would be an error and you would want to:
                  // disconnectGattServer();
              }
          }
  
  
  
      }
  }
  </code></pre>