title: How to connect Android app to ESP32 via bluetooth?
body: <p>I am trying to send a Time of Flight sensor (VL53L0X) data, which is integer through ESP32 board via bluetooth to the android app, that I am developing in Android Studio, but I am not able to connect to the board for some reason. I am still kind of a noob with android development and micro controllers. I would really appreciate all the help that I can get.</p>
  
  <p>When trying to connect to the board by running <strong>bluetoothSocket.connect();</strong>
  I get this exception: <strong>java.io.IOException: read failed, socket might closed or timeout, read ret: -1</strong></p>
  
  <p>I think the problem is with UUID, but I am not 100% sure.</p>
  
  <p>Here is the android studio code:</p>
  
  <pre><code>package fi.jamk.tof;
  
  import androidx.appcompat.app.AppCompatActivity;
  
  import android.bluetooth.BluetoothAdapter;
  import android.bluetooth.BluetoothDevice;
  import android.bluetooth.BluetoothManager;
  import android.bluetooth.BluetoothSocket;
  import android.content.Context;
  import android.content.Intent;
  import android.os.AsyncTask;
  import android.os.Bundle;
  import android.view.View;
  import android.widget.Button;
  import android.widget.TextView;
  import android.widget.Toast;
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.util.Set;
  import java.util.UUID;
  
  public class MainActivity extends AppCompatActivity {
  
      private boolean showingBtnText = false;
      private static TextView textViewStatus, textViewDistance, textViewPaired;
  
      private final static int REQUEST_ENABLE_BT = 1;
      private static final int REQUEST_DISCOVER_BT = 0;
  
      private static BluetoothAdapter bluetoothAdapter;
      private static BluetoothSocket bluetoothSocket;
      private static BluetoothDevice bluetoothDevice;
  
      static final UUID myUUID = UUID.fromString("65a8c5ed-3a5b-4f53-8b59-26277adcb1de");
      static final UUID serviceUUID = UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
  
      private final static String MAC = "30:AE:A4:1F:A0:2A";
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
          textViewStatus = (TextView) findViewById(R.id.textViewStatus);
          textViewDistance = (TextView) findViewById(R.id.textViewDistance);
          textViewPaired = (TextView) findViewById(R.id.textViewPaired);
  
          final BluetoothManager bluetoothManager =
                  (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
          bluetoothAdapter = bluetoothManager.getAdapter();
  
          if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
              textViewStatus.setText("Bluetooth is not enabled, enabling bluetooth");
              Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
              startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
          }
  
          textViewPaired.setText("Paired devices:");
          Set&lt;BluetoothDevice&gt; devices = bluetoothAdapter.getBondedDevices();
          for(BluetoothDevice device : devices){
              textViewPaired.append("\nDevice: " + device.getName() + ", " + device);
          }
  
          try{
              bluetoothDevice = bluetoothAdapter.getRemoteDevice(MAC);
              bluetoothSocket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(myUUID);
              bluetoothSocket.connect();
          } catch (IOException ex){
              Toast toast = Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG);
              toast.show();
          }
  
  
  
  
          final Button btnScan = (Button) findViewById(R.id.btnScan);
          btnScan.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  if(showingBtnText == true){
                      btnScan.setText("Scan");
                      showingBtnText = false;
                      textViewStatus.setText("Scan complete");
                      int distance = getData();
                      textViewDistance.setText(distance);
                  } else {
                      btnScan.setText("Stop Scanning");
                      showingBtnText = true;
                      textViewStatus.setText("Scanning...");
                  }
              }
          });
      }
  
  
      private int getData(){
          int distance;
          if (bluetoothSocket != null) {
              try {
                  InputStream data = bluetoothSocket.getInputStream();
                  String dataToString = getStringFromInputStream(data);
                  distance = Integer.parseInt(dataToString);
                  return distance;
              } catch (IOException e) {
                  Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
                  return  0;
              }
  
          } else{
              return 0;
          }
      }
  
      private static String getStringFromInputStream(InputStream is) {
  
          BufferedReader br = null;
          StringBuilder sb = new StringBuilder();
  
          String line;
          try {
  
              br = new BufferedReader(new InputStreamReader(is));
              while ((line = br.readLine()) != null) {
                  sb.append(line);
              }
  
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
              if (br != null) {
                  try {
                      br.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
  
          return sb.toString();
      }
  }
  </code></pre>
  
  <p>Here is the Arduino IDE code:</p>
  
  <pre><code>/* This example shows how to get single-shot range
   measurements from the VL53L0X. The sensor can optionally be
   configured with different ranging profiles, as described in
   the VL53L0X API user manual, to get better performance for
   a certain application. This code is based on the four
   "SingleRanging" examples in the VL53L0X API.
  
   The range readings are in units of mm. */
  
  #include &lt;Wire.h&gt;
  #include &lt;VL53L0X.h&gt;
  #include &lt;MedianFilter.h&gt;
  
  #include &lt;BLEDevice.h&gt;
  #include &lt;BLEUtils.h&gt;
  #include &lt;BLEServer.h&gt;
  #include &lt;BLE2902.h&gt;
  
  BLECharacteristic *pCharacteristic;
  bool deviceConnected = false;
  float txValue = 0;
  const int readPin = 32; // Use GPIO number. See ESP32 board pinouts
  const int LED = 2; // Could be different depending on the dev board. I used the DOIT ESP32 dev board.
  
  //std::string rxValue; // Could also make this a global var to access it in loop()
  
  // See the following for generating UUIDs:
  // https://www.uuidgenerator.net/
  
  //#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
  
  #define SERVICE_UUID           "65a8c5ed-3a5b-4f53-8b59-26277adcb1de"
  #define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
  #define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
  
  class MyServerCallbacks: public BLEServerCallbacks {
      void onConnect(BLEServer* pServer) {
        deviceConnected = true;
      };
  
      void onDisconnect(BLEServer* pServer) {
        deviceConnected = false;
      }
  };
  
  class MyCallbacks: public BLECharacteristicCallbacks {
      void onWrite(BLECharacteristic *pCharacteristic) {
        std::string rxValue = pCharacteristic-&gt;getValue();
  
        if (rxValue.length() &gt; 0) {
          Serial.println("*********");
          Serial.print("Received Value: ");
  
          for (int i = 0; i &lt; rxValue.length(); i++) {
            Serial.print(rxValue[i]);
          }
  
          Serial.println("*********");
        }
      }
  };
  
  VL53L0X sensor;
  
  MedianFilter test(10, 0);
  
  // Uncomment this line to use long range mode. This
  // increases the sensitivity of the sensor and extends its
  // potential range, but increases the likelihood of getting
  // an inaccurate reading because of reflections from objects
  // other than the intended target. It works best in dark
  // conditions.
  
  //#define LONG_RANGE
  
  
  // Uncomment ONE of these two lines to get
  // - higher speed at the cost of lower accuracy OR
  // - higher accuracy at the cost of lower speed
  
  //#define HIGH_SPEED
  //#define HIGH_ACCURACY
  
  int val;
  
  void setup()
  {
    Serial.begin(115200);
    Wire.begin();
  
      pinMode(LED, OUTPUT);
  
    // Create the BLE Device
    BLEDevice::init("ESP32 UART Test"); // Give it a name
  
    // Create the BLE Server
    BLEServer *pServer = BLEDevice::createServer();
    pServer-&gt;setCallbacks(new MyServerCallbacks());
  
    // Create the BLE Service
    BLEService *pService = pServer-&gt;createService(SERVICE_UUID);
  
    // Create a BLE Characteristic
    pCharacteristic = pService-&gt;createCharacteristic(
                        CHARACTERISTIC_UUID_TX,
                        BLECharacteristic::PROPERTY_NOTIFY
                      );
  
    pCharacteristic-&gt;addDescriptor(new BLE2902());
  
    BLECharacteristic *pCharacteristic = pService-&gt;createCharacteristic(
                                           CHARACTERISTIC_UUID_RX,
                                           BLECharacteristic::PROPERTY_WRITE
                                         );
  
    pCharacteristic-&gt;setCallbacks(new MyCallbacks());
  
    // Start the service
    pService-&gt;start();
  
    // Start advertising
    pServer-&gt;getAdvertising()-&gt;start();
    Serial.println("Waiting a client connection to notify...");
  
    sensor.init();
    sensor.setTimeout(500);
  
  #if defined LONG_RANGE
    // lower the return signal rate limit (default is 0.25 MCPS)
    sensor.setSignalRateLimit(0.1);
    // increase laser pulse periods (defaults are 14 and 10 PCLKs)
    sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
    sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
  #endif
  
  #if defined HIGH_SPEED
    // reduce timing budget to 20 ms (default is about 33 ms)
    sensor.setMeasurementTimingBudget(20000);
  #elif defined HIGH_ACCURACY
    // increase timing budget to 200 ms
    sensor.setMeasurementTimingBudget(200000);
  #endif
  }
  
  void loop()
  {
    if (deviceConnected){
  
      val = sensor.readRangeSingleMillimeters();
  
      test.in(val);
      val = test.out();
  
      pCharacteristic-&gt;setValue(val);
      pCharacteristic-&gt;notify();
  
      //Serial.print(val);
      if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }
  
      Serial.println();
    }
  }
  </code></pre>