0

In my app, I open and close a Bluetooth socket on the same device each session and listen for data. When I close one, I make sure to close the input and output streams and then socket in a cancel method. Still, for some people the app keeps trying to read from the device. I know because I read logs that are from run() in the listening thread, where there is a flag for listening that's set to false in cancel, and the listening thread will end when the socket is closed due to an IOException, but this never happens, so the socket must still be opened. I see logs of attempted reads every second of every day even though the person isn't using the app. This might be because the app crashes and the cancel method isn't called. Either way I can't guarantee the cancel method will be called. How do I close any Bluetooth sockets that were previously opened when I start up my app, if these were all opened in new threads created independently?

This guy had the same problem but I didn't see any solution: Android bluetooth connection doesn't close after application crash

The accepted answer is no good because:

  1. The current users haven't had the UncaughtExceptionHandler run that code yet and they need to have any previous connections closed when the new version is released

  2. The UncaughtExceptionHandler must have a reference to the sockets, which it doesn't have. I want to be able to close any Bluetooth sockets when the app starts.

  3. The guy who made that question asked how to get information about the socket to store for when the app starts up and you want to close them, and got no response.

EDIT:

How I open the socket (removed logging code):

        try {
            tmp.connect();;
        } catch (IOException e) {
            isConnected = false;
                try {
                    tmp = (BluetoothSocket) device.getClass().getMethod("createRfcommSocket",
                            new Class[] {int.class}).invoke(device, 1);
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
                try {
                    tmp.connect();
                    setConnected();
                } catch (IOException e1) {
                    e1.printStackTrace();
                    isConnected = false;
                    cancel();
                }

How I close the socket:

    public void cancel() {

        isConnected = false;
        listening = false;
        try {
            if (manageConnection.mmInStream != null) {
                manageConnection.mmInStream.close();
                manageConnection.mmInStream = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            if (manageConnection.mmOutStream != null) {
                manageConnection.mmOutStream.close();
                manageConnection.mmOutStream = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            mmSocket.close();
            mmSocket = null;
            manageConnection = null;
        } catch (IOException e) {
              // Logging code
        }
    }
}

Listening:

        while (listening == true) {
            try {

                synchronized (ListeningActivity.lock) {
                    buffer = new byte[mmInStream.available()];

                    mmInStream.read(buffer);
....

            } catch (IOException e) {
                // Code that calls cancel()
Questioner
  • 2,451
  • 4
  • 29
  • 50
  • Could you please share more details on how you open/close socket and how are you stopping thread? We need more info to understand what is the problem. Thanks – j2ko Jul 28 '17 at 12:17
  • @j2ko I edited my question to add some source code – Questioner Jul 28 '17 at 12:54
  • Is listening part is in manageConnection class ? So you directly make mmInStream = null after closing the socket - right? Are you sure that duaring InStream closure IOException doesn't happen before nulling that reference ? – j2ko Jul 28 '17 at 14:22
  • I can't say what is happening in every case. I just tested it there and that didn't happen, but I can't say it doesn't ever happen. If IOException happens, there isn't a problem. The problem is when the socket doesn't close at all because the cancel method isn't being called. – Questioner Jul 28 '17 at 15:09
  • I just tested it again there and it is still connected and can't disconnect because the reference to the socket is lost. This happened when I clicked the connect button on my app a few times in a row. – Questioner Jul 28 '17 at 15:45

0 Answers0