title: How to read and parse data in Java with HandleMessage method?
body: <p>I am building an android app that will be able to read values from a load sensor. The load sensor is connected to a LCD to display the values of weight applied to the sensor and an Arduino board. I am simply building this app to get the weight values from the LCD/load sensor. I am using HC-06 Bluetooth module, and I am able to connect/pair with this device successfully. The 'MainActivity' activity has a 'get data' button to read the data from the load sensor but anytime It is pressed the app freezes. I have been told by the author of the following tutorial that I need to write some 'Handler' method. I have made an attempt with no luck. </p>
  
  <p>I've been following this tutorial but I'm stuck on reading data </p>
  
  <p><a href="https://wingoodharry.wordpress.com/2014/04/15/android-sendreceive-data-with-arduino-using-bluetooth-part-2/" rel="nofollow">https://wingoodharry.wordpress.com/2014/04/15/android-sendreceive-data-with-arduino-using-bluetooth-part-2/</a></p>
  
  <p>Here is my code :</p>
  
  <pre><code>package com.proj.splate;
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.util.UUID;
  import android.app.Activity;
  import android.bluetooth.BluetoothAdapter;
  import android.bluetooth.BluetoothDevice;
  import android.bluetooth.BluetoothSocket;
  import android.content.Intent;
  import android.os.Bundle;
  import android.os.Handler;
  import android.os.HandlerThread;
  import android.os.Looper;
  import android.os.Message;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.widget.Button;
  import android.widget.TextView;
  import android.widget.Toast;
  
  @SuppressWarnings("unused")
  public class MainActivity extends Activity {
  
    Button btnscan;
    TextView txtArduino, txtString, txtStringLength, calorie;
    Handler bluetoothIn;
  
    final int handlerState = 0;                        //used to identify handler message
    private BluetoothAdapter btAdapter = null;
    private BluetoothSocket btSocket; //= null;
    private StringBuilder recDataString = new StringBuilder();
  
    private ConnectedThread mConnectedThread;
  
    // SPP UUID service - this should work for most devices
    private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
  
    // String for MAC address
    private static String address;
  
    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
  
      setContentView(R.layout.activity_main);
  
      //Link the buttons and textViews to respective views                
      btnscan = (Button) findViewById(R.id.scanBtn);             
      txtString = (TextView) findViewById(R.id.txtString); 
      txtStringLength = (TextView) findViewById(R.id.testView1); 
  
      bluetoothIn = new Handler() {
          public void handleMessage(android.os.Message msg) {
              if (msg.what == handlerState) { 
                  String readMessage = (String) msg.obj; 
                  recDataString.append(readMessage);
                  int endOfLineIndex = recDataString.indexOf("~"); 
                  if (endOfLineIndex &gt; 0) { 
                      String dataInPrint = recDataString.substring(0, endOfLineIndex); 
                      txtString.setText("Data Received = " + dataInPrint);                
                      int dataLength = dataInPrint.length();  
                      txtStringLength.setText("String Length = " + String.valueOf(dataLength));
  
                      if (recDataString.charAt(0) == '#') 
                      {
                          //get sensor value from string between indices 1-20
                          String weight = recDataString.substring(1, 20);
                          //update the textviews with sensor values
                          calorie.setText(weight + "kg");
  
                      }
                      recDataString.delete(0, recDataString.length());                    
                     // strIncom =" ";
                      dataInPrint = " ";
                  }            
              }
          }
      };
  
      btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
      checkBTState();  
  
    // Set up onClick listeners for button to scan for data
      btnscan.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
          mConnectedThread.write("0");
        }
      });
  }
  
    private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
  
        return  device.createRfcommSocketToServiceRecord(BTMODULEUUID);
        //creates secure outgoing connecetion with BT device using UUID
    }
  
    @Override
    public void onResume() {
      super.onResume();
  
      //Get MAC address from DeviceListActivity via intent
      Intent intent = getIntent();
  
      //Get the MAC address from the DeviceListActivty via EXTRA
      address = intent.getStringExtra(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
  
      //create device and set the MAC address
      BluetoothDevice device = btAdapter.getRemoteDevice(address);
  
      try {
          btSocket = createBluetoothSocket(device);
      } catch (IOException e) {
          Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_LONG).show();
      }  
      // Establish the Bluetooth socket connection.
      try 
      {
        btSocket.connect();
      } catch (IOException e) {
        try 
        {
          btSocket.close();
        } catch (IOException e2) 
        {
          //insert code to deal with this 
        }
      } 
      mConnectedThread = new ConnectedThread(btSocket);
      mConnectedThread.start();
  
      //I send a character when resuming.beginning transmission to check device is connected
      //If it is not an exception will be thrown in the write method and finish() will be called
      mConnectedThread.write("x");
    }
  
    @Override
    public void onPause() 
    {
      super.onPause();
      try
      {
      //Don't leave Bluetooth sockets open when leaving activity
        btSocket.close();
      } catch (IOException e2) {
          //insert code to deal with this 
      }
    }
  
   //Checks that the Android device Bluetooth is available and prompts to be turned on if off 
    private void checkBTState() {
  
      if(btAdapter==null) { 
          Toast.makeText(getBaseContext(), "Device does not support bluetooth", Toast.LENGTH_LONG).show();
      } else {
        if (btAdapter.isEnabled()) {
        } else {
          Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
          startActivityForResult(enableBtIntent, 1);
        }
      }
    }
  
    //create new class for connect thread
    private class ConnectedThread extends Thread {
          private final InputStream mmInStream;
          private final OutputStream mmOutStream;
  
          //creation of the connect thread
          public ConnectedThread(BluetoothSocket socket) {
              btSocket = socket;
              InputStream tmpIn = null;
              OutputStream tmpOut = null;
  
              try {
                  //Create I/O streams for connection
                  tmpIn = socket.getInputStream();
                  tmpOut = socket.getOutputStream();
              } catch (IOException e) { }
  
              mmInStream = tmpIn;
              mmOutStream = tmpOut;
          }
  
          public void run() {
              byte[] buffer = new byte[1024];  
              int bytes; 
  
              // Keep looping to listen for received messages
              while (true) {
                  try {
                      bytes = mmInStream.read(buffer);
                      bluetoothIn.obtainMessage(handlerState, bytes, -1, buffer).sendToTarget(); 
                  } catch (IOException e) {
                      break;
                  }
              }
          }
  
          //write method
          public void write(String input) {
              byte[] msgBuffer = input.getBytes();//converts entered String into bytes
              try {
                  mmOutStream.write(msgBuffer);//write bytes over BT connection via outstream
              } catch (IOException e) {  
                  //if you cannot write, close the application
                  Toast.makeText(getBaseContext(), "Connection Failed", Toast.LENGTH_LONG).show();
                  finish();
  
                }
              }
  
          public class BluetoothInHandler extends Handler{
              private Looper sLooper = null;
  
              private Handler mWorkerThreadHandler;
  
              final int handlerState = 0;                        //used to identify handler message
  
  
              protected class WorkerArgs {
                  Handler handler;
                  String input;
                  String output;
              }
  
  
              public BluetoothInHandler() {
                  super();
                  synchronized (BluetoothInHandler.class) {
                      if (sLooper == null) {
                          HandlerThread thread = new HandlerThread("AsyncWorker");
                          thread.start();
  
                          sLooper = thread.getLooper();
                      }
                  }
                  mWorkerThreadHandler = new WorkerHandler(sLooper);
              }
  
              @Override
              public void handleMessage(Message msg) {
                  if (msg.what == handlerState) {
                      WorkerArgs args = (WorkerArgs) msg.obj;
                      String readMessage = args.output;
                      //your job;
                  } else {
                      super.handleMessage(msg);
                  }
              }
  
              public void write(String input) {
                  WorkerArgs args = new WorkerArgs();
                  args.handler = this;
                  args.input = input;
                  Message message = mWorkerThreadHandler.obtainMessage(handlerState);
                  message.obj = args;
                  mWorkerThreadHandler.sendMessage(message);
              }
  
              protected class WorkerHandler extends Handler {
                  public WorkerHandler(Looper looper) {
                      super(looper);
                  }
  
  
  
                  @Override
                  public void handleMessage(Message msg) {
                      if (msg.what == handlerState) {
                          WorkerArgs args = (WorkerArgs) msg.obj;
                          byte[] buffer;
                          //the code here run in a thread, not in the ui thread
                          //do your job like:
                          byte[] bytes = mmInStream.read(buffer);
  
  
                          args.output = new String(bytes);
                          Message message = args.handler.obtainMessage(handlerState);
                          message.obj = args;
                          message.sendToTarget();
                      }
                  }
              }
  
          }
  
          }//ConnectedThread End              
  
  }
  </code></pre>
  
  <p>Here is my Arduino Code:</p>
  
  <pre><code>#include &lt;LiquidCrystal.h&gt;
  
  int led = 13;
  int button = 12;
  
  LiquidCrystal lcd(9, 8, 4, 5, 6, 7);
  // Pins used for inputs and outputs********************************************************
  
  float sensorValue1;
  float containerValue;
  char inbyte = 0;
  int flag;
  const int numReadings = 50;
  int readings[numReadings];
  int index = 0;
  int total = 0;
  int average = 0;
  
  
  
  //*******************************************************************************************
  
  void setup()
  {
  
    pinMode(led, OUTPUT);
    digitalWrite(led, HIGH);
    Serial.begin(9600);
  
    for (int thisReading = 0; thisReading &lt; numReadings; thisReading++)
    {
        readings[thisReading] = 0;
    }
  
    lcd.begin(16, 2); //change to 16, 2 for smaller 16x2 screens
    lcd.clear();
    lcd.print("hello, world!");
    delay (1000);
    lcd.clear();
    delay (500);
  
  }
  
  void loop() 
  {
    digitalWrite(led, HIGH); 
    readSensor2();    //DONE
  
  
    printLCD();       //DONE
    return;
  
   sendAndroidValues();
  
    //when serial values have been received this will be true
    if (Serial.available() &gt; 0)
    {
      inbyte = Serial.read();
      if (inbyte == '0')
      {
        //LED off
        digitalWrite(led, LOW);
      }
      if (inbyte == '1')
      {
        //LED on
        digitalWrite(led, HIGH);
      }
    }
  
    //delay by 2s. Meaning we will be sent values every 2s approx
    //also means that it can take up to 2 seconds to change LED state
    delay(2000);
  
  
  void readSensor2()
  {
    total = total - readings[index];
  
    readings[index] = analogRead(A0);
  
    total = total + readings[index];
  
    index = index + 1;
  
    if (index &gt;= numReadings)
    {
       index = 0;
    }
  
    average = total / numReadings;
  
  
  
     //sensorValue1 = (analogRead(A0) - 330)* i;
     //delay(200);
  
  
     Serial.println(average);
     delay(100);
  
  
     if( digitalRead(button) == HIGH &amp;&amp; flag == 1)
    {
      flag = 0;
      containerValue = 0; 
  
    }
    else if (digitalRead(button) == HIGH &amp;&amp; flag != 1)
   {
    flag = 1;                        //when the button is pressed the initially sesnsor 
      containerValue = sensorValue1;  
      delay(10);
    }
  
    //Serial.println(digitalRead(button));
     delay (1000);
  
  }
  
  //sends the values from the sensor over serial to BT module
  void sendAndroidValues()
   {
    //puts # before the values so our app knows what to do with the data
   Serial.print('#');
    //for loop cycles through 4 sensors and sends values via serial
    Serial.print(sensorValue1);
    Serial.print('+');
      //technically not needed but I prefer to break up data values
      //so they are easier to see when debugging
   Serial.print('~'); //used as an end of transmission character - used in app for string length
   Serial.println();
   delay(5000);        //added a delay to eliminate missed transmissions
  }
  
  void printLCD()
  {
    lcd.setCursor(4, 0);
    lcd.print("   GRAMS    ");
    lcd.setCursor(4, 1);
    lcd.print(sensorValue1);
  }  
  </code></pre>