I am writing an app to control an arduino and to read from arduino sensors. The writing to the arduino works fine, but the reading from arduino is not functioning.
I have a handler created in the onCreate method, and a dedicated read thread that loops continuously.
However the read thread never gets called because whenever the program calls btSocket.connect() it throws the error
V/TAG: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
socket.connect() is called in an onclicklistner shown here
btnRead.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if (myBluetooth != null) {
try {
btSocket.connect();
Log.v(str, "Socket Connected");
read = new readThread(btSocket);
read.start();
Log.v(str, "READ THREAD STARTED");
} catch (IOException e) {
Log.v(str, "Catch on bt.connect");
Log.v(str, e.toString());
try {
btSocket.close();
} catch (IOException e2) {
//insert code to deal with this
}
}
}
}
});
I don't understand why it isnt working there, since the socket.connect() method works elsewhere in the code (otherwise how would I be writing to the bluetooth).
this method is being called in onCreate and seems to work fine.
private class ConnectBT extends AsyncTask<Void, Void, Void> // UI thread
{
private boolean ConnectSuccess = true; //if it's here, it's almost connected
@Override
protected void onPreExecute()
{
progress = ProgressDialog.show(ledControl.this, "Connecting...", "Please wait!!!"); //show a progress dialog
}
@Override
protected Void doInBackground(Void... devices) //while the progress dialog is shown, the connection is done in background
{
try
{
if (btSocket == null || !isBtConnected)
{
myBluetooth = BluetoothAdapter.getDefaultAdapter();//get the mobile bluetooth device
BluetoothDevice device = myBluetooth.getRemoteDevice(address);//connects to the device's address and checks if it's available
btSocket = device.createInsecureRfcommSocketToServiceRecord(myUUID);//create a RFCOMM (SPP) connection
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
btSocket.connect();//start connection
}
}
catch (IOException e)
{
ConnectSuccess = false;//if the try failed, you can check the exception here
}
return null;
}
@Override
protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
{
super.onPostExecute(result);
if (!ConnectSuccess)
{
msg("Connection Failed. Is it a SPP Bluetooth? Try again.");
finish();
}
else
{
msg("Connected.");
isBtConnected = true;
}
progress.dismiss();
}
}
}
So why isn't the socket connected in the onclicklistener?
Here is the code in its entirety:
package com.example.dustin.arduino_test;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.os.AsyncTask;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
public class ledControl extends ActionBarActivity {
Button btnOn, btnOff, btnDis, btnRead;
SeekBar brightness;
TextView lumn;
String address = null;
TextView potRead;
private ProgressDialog progress;
BluetoothAdapter myBluetooth = null;
BluetoothSocket btSocket = null;
private boolean isBtConnected = false;
//SPP UUID. Look for it
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
Handler blueToothIn;
private StringBuilder recDataString = new StringBuilder();
private readThread read;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent newint = getIntent();
address = newint.getStringExtra(DeviceList.EXTRA_ADDRESS);
//view of the ledControl
setContentView(R.layout.activity_led_control);
//call the widgtes
btnOn = (Button)findViewById(R.id.button2);
btnOff = (Button)findViewById(R.id.button3);
btnDis = (Button)findViewById(R.id.button4);
btnRead = (Button)findViewById(R.id.Read);
brightness = (SeekBar)findViewById(R.id.seekBar);
lumn = (TextView)findViewById(R.id.lumn);
potRead = (TextView)findViewById(R.id.PotReading);
final String str = "TAG";
new ConnectBT().execute(); //Call the class to connect
blueToothIn = new Handler(){
public void handleMessage(android.os.Message msg) {
String readMessage = (String) msg.obj;
recDataString.append(readMessage);
int endOfLineIndex = recDataString.indexOf("~");
if (endOfLineIndex > 0) {
String dataInPrint = recDataString.substring(0, endOfLineIndex);
if (recDataString.charAt(0) == '#') {
String potVal = recDataString.toString();
Log.v(str, "set pot text");
potRead.setText(potVal);
Log.v(str, potVal);
}
recDataString.delete(0,recDataString.length());
}
}
};
//commands to be sent to bluetooth
btnRead.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if (myBluetooth != null) {
try {
btSocket.connect();
Log.v(str, "Socket Connected");
read = new readThread(btSocket);
read.start();
Log.v(str, "READ THREAD STARTED");
} catch (IOException e) {
Log.v(str, "Catch on bt.connect");
Log.v(str, e.toString());
try {
btSocket.close();
} catch (IOException e2) {
//insert code to deal with this
}
}
}
}
});
btnOn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
turnOnLed(); //method to turn on
}
});
btnOff.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
turnOffLed(); //method to turn off
}
});
btnDis.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Disconnect(); //close connection
}
});
brightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser==true)
{
lumn.setText(String.valueOf(progress));
try
{
btSocket.getOutputStream().write(progress);
}
catch (IOException e)
{
msg("Bluetooth socket exception");
}
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
private class readThread extends Thread{
private final InputStream btIn;
String str = "READ THREAD";
private readThread(BluetoothSocket socket){
InputStream tmpIn = null;
try{
tmpIn = socket.getInputStream();
Log.v(str, "Input Stream Test");
}catch (Exception e){
Log.v(str, "Exception");
Log.v(str, e.toString());
}
btIn = tmpIn;
}
public void run(){
byte[] buffer = new byte[256];
int bytes;
if(btSocket !=null){
while(true) {
try {
Log.v(str, "Got to run method");
bytes = btIn.read(buffer); /// this does not work
String readMessage = new String(buffer, 0, bytes);
//Send the obtained bytes to the UI Activity via handler
blueToothIn.obtainMessage(0, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
Log.v(str, e.toString());
}
}
}
}
}
private void Disconnect()
{
if (btSocket!=null) //If the btSocket is busy
{
try
{
btSocket.close(); //close connection
}
catch (IOException e)
{ msg("Error");}
}
finish(); //return to the first layout
}
private void turnOffLed()
{
if (btSocket!=null)
{
try
{
btSocket.getOutputStream().write(0);
}
catch (IOException e)
{
msg("Error");
}
}
}
private void turnOnLed()
{
if (btSocket!=null)
{
try
{
btSocket.getOutputStream().write(255);
}
catch (IOException e)
{
msg("Error");
}
}
}
// fast way to call Toast
private void msg(String s)
{
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_led_control, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class ConnectBT extends AsyncTask<Void, Void, Void> // UI thread
{
private boolean ConnectSuccess = true; //if it's here, it's almost connected
@Override
protected void onPreExecute()
{
progress = ProgressDialog.show(ledControl.this, "Connecting...", "Please wait!!!"); //show a progress dialog
}
@Override
protected Void doInBackground(Void... devices) //while the progress dialog is shown, the connection is done in background
{
try
{
if (btSocket == null || !isBtConnected)
{
myBluetooth = BluetoothAdapter.getDefaultAdapter();//get the mobile bluetooth device
BluetoothDevice device = myBluetooth.getRemoteDevice(address);//connects to the device's address and checks if it's available
btSocket = device.createInsecureRfcommSocketToServiceRecord(myUUID);//create a RFCOMM (SPP) connection
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
btSocket.connect();//start connection
}
}
catch (IOException e)
{
ConnectSuccess = false;//if the try failed, you can check the exception here
}
return null;
}
@Override
protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
{
super.onPostExecute(result);
if (!ConnectSuccess)
{
msg("Connection Failed. Is it a SPP Bluetooth? Try again.");
finish();
}
else
{
msg("Connected.");
isBtConnected = true;
}
progress.dismiss();
}
}
}