title: Read and notify BLE android
body: <p>I wrote a code in which I am able to read a notify value from a hear rate sensor when it changes.</p>
  
  <p>But I need also to read the battery level of the device, which is another service from the emulated device, but whenever I try to read the battery value, the first part don't even send the notify values from the heart rate.</p>
  
  <p>Here is the code:</p>
  
  <pre><code>public class MainActivity extends AppCompatActivity {
  
  BluetoothManager btManager;
  BluetoothAdapter btAdapter;
  BluetoothLeScanner btScanner;
  Button startScanningButton;
  Button stopScanningButton;
  TextView peripheralTextView;
  private final static int REQUEST_ENABLE_BT = 1;
  private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
  
  Boolean btScanning = false;
  int deviceIndex = 0;
  ArrayList&lt;BluetoothDevice&gt; devicesDiscovered = new ArrayList&lt;BluetoothDevice&gt;();
  EditText deviceIndexInput;
  Button connectToDevice;
  Button disconnectDevice;
  BluetoothGatt bluetoothGatt;
  
  UUID HEART_RATE_SERVICE_UUID = convertFromInteger(0x180D);
  UUID HEART_RATE_MEASUREMENT_CHAR_UUID = convertFromInteger(0x2A37);
  UUID HEART_RATE_CONTROL_POINT_CHAR_UUID = convertFromInteger(0x2A39);
  UUID CLIENT_CHARACTERISTIC_CONFIG_UUID = convertFromInteger(0x2902);
  UUID BATTERY_LEVEL = convertFromInteger(0x2A19);
  UUID BATTERY_SERVICE = convertFromInteger(0x180F);
  
  public final static String ACTION_GATT_CONNECTED =
  "com.example.bluetooth.le.ACTION_GATT_CONNECTED";
  public final static String ACTION_GATT_DISCONNECTED =
  "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
  public final static String ACTION_GATT_SERVICES_DISCOVERED =
  "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
  public final static String ACTION_DATA_AVAILABLE =
  "com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
  public final static String EXTRA_DATA =
  "com.example.bluetooth.le.EXTRA_DATA";
  
  public Map&lt;String, String&gt; uuids = new HashMap&lt;String, String&gt;();
  
  // Stops scanning after 5 seconds.
  private Handler mHandler = new Handler();
  private static final long SCAN_PERIOD = 1000;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
      peripheralTextView = (TextView) findViewById(R.id.PeripheralTextView);
      peripheralTextView.setMovementMethod(new ScrollingMovementMethod());
      deviceIndexInput = (EditText) findViewById(R.id.InputIndex);
      deviceIndexInput.setText("0");
  
      connectToDevice = (Button) findViewById(R.id.ConnectButton);
      connectToDevice.setOnClickListener(new View.OnClickListener() {
          public void onClick(View v) {
              connectToDeviceSelected();
          }
      });
  
      disconnectDevice = (Button) findViewById(R.id.DisconnectButton);
      disconnectDevice.setVisibility(View.INVISIBLE);
      disconnectDevice.setOnClickListener(new View.OnClickListener() {
          public void onClick(View v) {
              disconnectDeviceSelected();
          }
      });
  
      startScanningButton = (Button) findViewById(R.id.StartScanButton);
      startScanningButton.setOnClickListener(new View.OnClickListener() {
          public void onClick(View v) {
              startScanning();
          }
      });
  
      stopScanningButton = (Button) findViewById(R.id.StopScanButton);
      stopScanningButton.setOnClickListener(new View.OnClickListener() {
          public void onClick(View v) {
              stopScanning();
          }
      });
      stopScanningButton.setVisibility(View.INVISIBLE);
  
      btManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
      btAdapter = btManager.getAdapter();
      btScanner = btAdapter.getBluetoothLeScanner();
  
      if (btAdapter != null &amp;&amp; !btAdapter.isEnabled()) {
          Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
          startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
      }
  
      // Make sure we have access coarse location enabled, if not, prompt the user to enable it
  /*        if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
          final AlertDialog.Builder builder = new AlertDialog.Builder(this);
          builder.setTitle("This app needs location access");
          builder.setMessage("Please grant location access so this app can detect peripherals.");
          builder.setPositiveButton(android.R.string.ok, null);
          builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
              @Override
              public void onDismiss(DialogInterface dialog) {
                  requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
              }
          });
          builder.show();
      }*/
  
  
  
      //client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
  }
  
  // Device scan callback.
  private ScanCallback leScanCallback = new ScanCallback() {
      @Override
      public void onScanResult(int callbackType, ScanResult result) {
          peripheralTextView.append("Index: " + deviceIndex + ", Device Name: " + result.getDevice().getName() + " rssi: " + result.getRssi() + ", MAC: " + result.getDevice().getAddress() + "\n");
          devicesDiscovered.add(result.getDevice());
          deviceIndex++;
          // auto scroll for text view
          final int scrollAmount = peripheralTextView.getLayout().getLineTop(peripheralTextView.getLineCount()) - peripheralTextView.getHeight();
          // if there is no need to scroll, scrollAmount will be &lt;=0
          if (scrollAmount &gt; 0) {
              peripheralTextView.scrollTo(0, scrollAmount);
          }
      }
  };
  
  // Device connect call back
  private final BluetoothGattCallback btleGattCallback = new BluetoothGattCallback() {
  
      @Override
      public void onCharacteristicChanged(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
          // this will get called anytime you perform a read or write characteristic operation
  
          final byte[] teste = characteristic.getValue();
  
          final String batida = teste.toString();
  
          final String result = "result";
  
          int format = BluetoothGattCharacteristic.FORMAT_UINT8;
  
          final int heartRate = characteristic.getIntValue(format, 1);
  
          String TAG = "d";
  
          Log.d(TAG, String.format("Received heart rate: %d", heartRate));
  
          Log.v(result , batida);
  
          MainActivity.this.runOnUiThread(new Runnable() {
              public void run() {
                  peripheralTextView.append("value of sensor (BPM) "+ heartRate + "\n");
              }
          });
      }
  
      @Override
      public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) {
          // this will get called when a device connects or disconnects
          System.out.println(newState);
          switch (newState) {
              case 0:
              MainActivity.this.runOnUiThread(new Runnable() {
                  public void run() {
                      peripheralTextView.append("device disconnected\n");
                      connectToDevice.setVisibility(View.VISIBLE);
                      disconnectDevice.setVisibility(View.INVISIBLE);
                  }
              });
              break;
              case 2:
              MainActivity.this.runOnUiThread(new Runnable() {
                  public void run() {
                      peripheralTextView.append("device connected\n");
                      connectToDevice.setVisibility(View.INVISIBLE);
                      disconnectDevice.setVisibility(View.VISIBLE);
                  }
              });
  
                  // discover services and characteristics for this device
              bluetoothGatt.discoverServices();
  
              break;
              default:
              MainActivity.this.runOnUiThread(new Runnable() {
                  public void run() {
                      peripheralTextView.append("we encounterned an unknown state, uh oh\n");
                  }
              });
              break;
          }
      }
  
      @Override
      public void onServicesDiscovered(final BluetoothGatt gatt, final int status) {
          // this will get called after the client initiates a            BluetoothGatt.discoverServices() call
          MainActivity.this.runOnUiThread(new Runnable() {
              public void run() {
                  peripheralTextView.append("device services have been discovered\n");
              }
          });
          displayGattServices(bluetoothGatt.getServices());
  
          BluetoothGattCharacteristic characteristic = gatt.getService(HEART_RATE_SERVICE_UUID).getCharacteristic(HEART_RATE_MEASUREMENT_CHAR_UUID);
  
          //BluetoothGattCharacteristic battery = gatt.getService(BATTERY_SERVICE).getCharacteristic(BATTERY_LEVEL);
  
          //gatt.readCharacteristic(battery);
  
          gatt.setCharacteristicNotification(characteristic, true);
  
          BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_UUID);
  
          descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
  
          gatt.writeDescriptor(descriptor);
      }
  
      @Override
      public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
          BluetoothGattCharacteristic characteristic = gatt.getService(HEART_RATE_SERVICE_UUID).getCharacteristic(HEART_RATE_CONTROL_POINT_CHAR_UUID);
  
          characteristic.setValue(new byte[]{1,1});
          gatt.writeCharacteristic(characteristic);
      }
  
      @Override
      // Result of a characteristic read operation
      public void onCharacteristicRead(BluetoothGatt gatt,
       BluetoothGattCharacteristic characteristic,
       int status) {
          if (status == BluetoothGatt.GATT_SUCCESS) {
              broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
          }
      }
  };
  
  private void broadcastUpdate(final String action,
   final BluetoothGattCharacteristic characteristic) {
  
      System.out.println(characteristic.getUuid());
  }
  
  @Override
  public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
      switch (requestCode) {
          case PERMISSION_REQUEST_COARSE_LOCATION: {
              if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                  System.out.println("coarse location permission granted");
              } else {
                  final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                  builder.setTitle("Functionality limited");
                  builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
                  builder.setPositiveButton(android.R.string.ok, null);
                  builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
  
                      @Override
                      public void onDismiss(DialogInterface dialog) {
                      }
  
                  });
                  builder.show();
              }
              return;
          }
      }
  }
  
  public void startScanning() {
      System.out.println("start scanning");
      btScanning = true;
      deviceIndex = 0;
      devicesDiscovered.clear();
      peripheralTextView.setText("");
      peripheralTextView.append("Started Scanning\n");
      startScanningButton.setVisibility(View.INVISIBLE);
      stopScanningButton.setVisibility(View.VISIBLE);
      AsyncTask.execute(new Runnable() {
          @Override
          public void run() {
              btScanner.startScan(leScanCallback);
          }
      });
  
      mHandler.postDelayed(new Runnable() {
          @Override
          public void run() {
              stopScanning();
          }
      }, SCAN_PERIOD);
  }
  
  public void stopScanning() {
      System.out.println("stopping scanning");
      peripheralTextView.append("Stopped Scanning\n");
      btScanning = false;
      startScanningButton.setVisibility(View.VISIBLE);
      stopScanningButton.setVisibility(View.INVISIBLE);
      AsyncTask.execute(new Runnable() {
          @Override
          public void run() {
              btScanner.stopScan(leScanCallback);
          }
      });
  }
  
  public void connectToDeviceSelected() {
      peripheralTextView.append("Trying to connect to device at index: " + deviceIndexInput.getText() + "\n");
      int deviceSelected = Integer.parseInt(deviceIndexInput.getText().toString());
      bluetoothGatt = devicesDiscovered.get(deviceSelected).connectGatt(this, false, btleGattCallback);
  }
  
  public void disconnectDeviceSelected() {
      peripheralTextView.append("Disconnecting from device\n");
      bluetoothGatt.disconnect();
  }
  
  private void displayGattServices(List&lt;BluetoothGattService&gt; gattServices) {
      if (gattServices == null) return;
  
      // Loops through available GATT Services.
      for (BluetoothGattService gattService : gattServices) {
  
          final String uuid = gattService.getUuid().toString();
          System.out.println("Service discovered: " + uuid);
          MainActivity.this.runOnUiThread(new Runnable() {
              public void run() {
                  peripheralTextView.append("Service disovered: "+uuid+"\n");
              }
          });
          new ArrayList&lt;HashMap&lt;String, String&gt;&gt;();
          List&lt;BluetoothGattCharacteristic&gt; gattCharacteristics =
          gattService.getCharacteristics();
  
          // Loops through available Characteristics.
          for (BluetoothGattCharacteristic gattCharacteristic :
              gattCharacteristics) {
  
              final String charUuid = gattCharacteristic.getUuid().toString();
          System.out.println("Characteristic discovered for service: " + charUuid);
          MainActivity.this.runOnUiThread(new Runnable() {
              public void run() {
                  peripheralTextView.append("Characteristic discovered for service: "+charUuid+"\n");
              }
          });
  
      }
  }
  }
  
  @Override
  public void onStart() {
      super.onStart();
  }
  
  @Override
  public void onStop() {
      super.onStop();
  
  }
  
  public UUID convertFromInteger(int i) {
      final long MSB = 0x0000000000001000L;
      final long LSB = 0x800000805f9b34fbL;
      long value = i &amp; 0xFFFFFFFF;
      return new UUID(MSB | (value &lt;&lt; 32), LSB);
  }
  
  }
  </code></pre>
  
  <p>How can I read without interrupting the notify from BLE?</p>