Search code examples
javaandroidbluetoothioexceptionobd-ii

IOException in Java (Android): Transport endpoint is not connected


In my Android application, which was copied from answer to this question (and then slightly changed due to UUID-related problems with Samsung Galaxy tabs) I successfully connect to OBD device via bluetooth.

Then, when I try to send any command (which is done by sendData()), the exception from the title (Transport endpoint is not connected) is thrown and nothing is sent.

When I connected to my computer (the only difference in code is hardware address), I can send command without any problem (of course, I don't get any response, since computer is not OBD-device). Therefore, I believe I got all the permissions I need and UUID address is fine also.

EDIT1: I installed Komunikacija.apk on the tablet again. I have only added some comments and have encountered two new problems:

  • mmSocket.connect() in openBT() fails (nothing happens for a long time after the last toast "5")
  • if bluetooth is turned off, the application shows a request for turning bluetoot on, but then "unfortunately stops".

EDIT2:

I went to the car again and test the app on Samsung phone and again onf the tablet also. Results:

  • tablet:
    • when running the application for the first time, connections, mentioned in EDIT1, wasn't made successfully.
    • I succeed in all of my next attempts, but IOException was thrown:
      • when I pressed the button SEND for the first time, exception.getMessage() returned Connection reset by peer
      • every next time, I got message Transport endpoint is not connected
  • phone: I successfully made a connection already in the first attempt, everything else was the same

EDIT3: I found out that the OBD-device EML327 was at least part of the problems, because today, I tested get another OBD-device (OBDLink LX) and everything works fine, if I use it. Now, the question is

Why are those two OBD-devices behaving completely different and how to fix errors which occur, if I use OBD327?

EDIT4: I didn't find this important earlier, but the only response from my EML327 was AT+BRSF=24. After googling it around, I found an answer.

My MainActivity.java:

package com.example.komunikacija;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
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.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
    TextView myLabel;
    EditText myTextbox;
    BluetoothAdapter mBluetoothAdapter;
    BluetoothSocket mmSocket;
    BluetoothDevice mmDevice;
    OutputStream mmOutputStream;
    InputStream mmInputStream;
    Thread workerThread;
    byte[] readBuffer;
    int readBufferPosition;
    int counter, stevec;
    volatile boolean stopWorker;

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button openButton = (Button)findViewById(R.id.open);
    Button sendButton = (Button)findViewById(R.id.send);
    Button closeButton = (Button)findViewById(R.id.close);
    myLabel = (TextView)findViewById(R.id.label);
    myTextbox = (EditText)findViewById(R.id.entry);

    //Open Button
    openButton.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v){
            try {
                findBT();
                openBT();
            }
            catch (IOException ex) { }
        }
    });

    //Send Button
    sendButton.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v){
            try{
                sendData();
            }
            catch (IOException ex) { 
                Toast.makeText(getApplicationContext(), "error when sending:"+ ex.getMessage(), Toast.LENGTH_SHORT).show();;

            }
        }
    });

    //Close button
    closeButton.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v){
            try 
            {
                closeBT();
            }
            catch (IOException ex) { }
        }
    });
}

void findBT() {
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if(mBluetoothAdapter == null){
        myLabel.setText("No bluetooth adapter available");
    }

    else{
        if (!mBluetoothAdapter.isEnabled()){
            Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBluetooth, 0);
        }

        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        Toast.makeText(this, "we found "+Integer.toString(pairedDevices.size()), Toast.LENGTH_SHORT).show();//number of devices found
        if(pairedDevices.size() > 0){
            for(BluetoothDevice device : pairedDevices){
                //computer's addres: "00:22:68:E6:7D:D7"
                //obd device's("00:0D:18:00:00:01")
                //device.getName().equals("MattsBlueTooth")
                if(device.getAddress().equals("00:22:68:E6:7D:D7")) {
                    Toast.makeText(this, "Found.", Toast.LENGTH_SHORT).show();
                    mmDevice = device;
                    break;
                }
            }
        }
        myLabel.setText("Bluetooth Device Found");

    }
}

void openBT() throws IOException{
    Toast.makeText(this, "openBT.", Toast.LENGTH_SHORT).show();
//      UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");   //Standard SerialPortService ID
    UUID uuid = mmDevice.getUuids()[0].getUuid();
    BluetoothSocket tmp = null;
    try {
        tmp = mmDevice.createRfcommSocketToServiceRecord(uuid);

        // for others devices its works with:
        // Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});

        // for galaxy tab 2 with:
        Method m = mmDevice.getClass().getMethod("createInsecureRfcommSocket", new Class[] {int.class});

        tmp = (BluetoothSocket) m.invoke(mmDevice, 1);
    } catch (IOException e) {

    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        Toast.makeText(this, "1", Toast.LENGTH_SHORT).show();;
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        Toast.makeText(this, "2", Toast.LENGTH_SHORT).show();;
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        Toast.makeText(this, "3", Toast.LENGTH_SHORT).show();;
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        Toast.makeText(this, "4", Toast.LENGTH_SHORT).show();;
    }
    mmSocket = tmp;
    Toast.makeText(this, "5", Toast.LENGTH_SHORT).show();;

    mmSocket.connect();
//        Log.i(TAG, "Client Connected!");


//      mmSocket = mmDevice.createInsecureRfcommSocketToServiceRecord(uuid);        
    Toast.makeText(this, "before connect", Toast.LENGTH_SHORT).show();
//      mmSocket.connect();
    Toast.makeText(this, "before stream", Toast.LENGTH_SHORT).show();
    mmOutputStream = mmSocket.getOutputStream();
    mmInputStream = mmSocket.getInputStream();
    Toast.makeText(this, "before listening", Toast.LENGTH_SHORT).show();

    beginListenForData();

    myLabel.setText("Bluetooth Opened");
}

void beginListenForData(){
    final Handler handler = new Handler(); 
    final byte delimiter = 10; //This is the ASCII code for a newline character
    final byte konec = 90; //ASCII for char Z

    stopWorker = false;
    readBufferPosition = 0;
    readBuffer = new byte[1024];
    workerThread = new Thread(new Runnable() {
        public void run(){                
           while(!Thread.currentThread().isInterrupted() && !stopWorker){
             try
                {
                    int bytesAvailable = mmInputStream.available();                        
                    if(bytesAvailable > 0)
                    {
                        byte[] packetBytes = new byte[bytesAvailable];
                        mmInputStream.read(packetBytes);
                        packetBytes[bytesAvailable - 1] = konec;

                        for(int i=0;i<bytesAvailable;i++)
                        {
                            byte b = packetBytes[i];

                            if(b == konec)//originally if(b == delimiter)
                            {
                                 byte[] encodedBytes = new byte[readBufferPosition];
                                 System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
                                 final String data = new String(encodedBytes, "US-ASCII");
                                 readBufferPosition = 0; 

                                handler.post(new Runnable()
                                {
                                    public void run()
                                    {
                                        Toast.makeText(getApplicationContext(), "setting " + Integer.toString(stevec++)+data, Toast.LENGTH_SHORT).show();

                                        myLabel.setText(data);
                                    }
                                });
                            }
                            else
                            {
                                readBuffer[readBufferPosition++] = b;
                            }
                        }
                    }
                } 
                catch (IOException ex) 
                {
                    stopWorker = true;
                }
           }
        }
    });

    workerThread.start();
}

void sendData() throws IOException {
    String msg = myTextbox.getText().toString();
    Toast.makeText(this, "sending:"+msg, Toast.LENGTH_SHORT).show();;

    //msg += "\n";    <-- dont want to have that.
    mmOutputStream.write(msg.getBytes());
    myLabel.setText("Data Sent");
}

void closeBT() throws IOException {
    stopWorker = true;
    mmOutputStream.close();
    mmInputStream.close();
    mmSocket.close();
    myLabel.setText("Bluetooth Closed");
}
}

Solution

  • I didn't just wait and the aswers to questions here and here helped me out of troubles. The problem was that EML327 needed channel 16, so the second argument of the method invoke should be 16.