0

I'm connecting 2 devices via bluetooth and when I press the logout button on one device I want to send a message to the other device (telling the other to also logout), close the bluetooth connection, and close the current activity (i.e. go back to my login activity)

The problem is I keep getting this exception which makes me think I'm not closing my connections properly:

java.io.IOException: bt socket closed, read return: -1
    at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:517)
    at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96)
    at java.io.InputStream.read(InputStream.java:162)
    at com.example.BTService$ConnectedThread.run(BTService.java:269)

BTService.java:269 is where the connectedThread is reading from the input stream

When logout is pressed, I basically destroy the MainActivity, and in onDestroy() I stop my bluetooth service:

this.stopService(new Intent(this, BTService.class))

Which should call onDestroy() of my service, which calls stopConnect():

public static void stopConnect(){
        if (connectThread != null) {
            connectThread.cancel();
            connectThread = null;
        }

        if (connectedThread != null) {
            connectedThread.cancel();
            connectedThread = null;
        }
    }

So as soon as the service is destroyed by clicking logout, the cancel() method of my connectedThread should be called:

public static class ConnectedThread extends Thread {
        private BluetoothSocket mmSocket;
        private InputStream mmInStream;
        private OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;

            //Tell other phone that we have connected
            write("connected".getBytes());
        }

        public void run() {
            byte[] buffer = new byte[1024];  // buffer store for the stream
            int bytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs
            while (!this.isInterrupted()) {
                try {
                    // Read from the InputStream
                    bytes = mmInStream.read(buffer);
                    // Send the obtained bytes to the UI activity
                    mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
                            .sendToTarget();
                } catch (IOException e) {
                    e.printStackTrace();
                    break;
                }
            }
        }

        /* Call this from the main activity to send data to the remote device */
        public void write(byte[] bytes) {
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            if (mmInStream != null) {
                try {mmInStream.close();} catch (Exception e) {}
                mmInStream = null;
            }

            if (mmOutStream != null) {
                try {mmOutStream.close();} catch (Exception e) {}
                mmOutStream = null;
            }

            if (mmSocket != null) {
                try {mmSocket.close();} catch (Exception e) {}
                mmSocket = null;
            }

            this.interrupt();
        }
    }

I thought I was doing this correctly by first closing my input and output streams, then closing the socket, and then closing the thread. I got this from an answer here: Disconnect a bluetooth socket in Android

However, as soon as logout is pressed, I get the ioexception as its still trying to read from the input stream. I have also tried placing my input/output/socket close code in a method outside of the ConnectedThread class but that results in the same issue

Community
  • 1
  • 1
Simon
  • 9,762
  • 15
  • 62
  • 119
  • What exactly is the problem? You closed the socket while you were reading from it, so you got the 'socket closed' exception. That's exactly what should happen. – user207421 Jun 24 '16 at 00:47
  • I'm thinking it would be better to stop trying to read from it before closing the socket no? Hence why I try to close the input stream before closing the socket but its still throwing that exception – Simon Jun 24 '16 at 01:00

1 Answers1

0

There is sample project 'android bluetooth chat', it looks like you use slightely modified code from there. But, in that example, all methods are synchronized and bluetooth service has variable for current state. Maybe, that is the issue-bluetooth socket is closed already, but thread is still around

Alex Shutov
  • 3,217
  • 2
  • 13
  • 11