I have a project that connects to a device over Bluetooth. It used to work fairly reliably, but now it fails the BluetoothSocket.connect()
call every time. (Well, I got it to connect once during the thousands of attempts over a 4 hour period.) Most of the code has been taken from the standard sample chat code in the API, with the exception of the common modification in getting the BluetoothSocket
device itself:
Method m = device.getClass().getMethod(
"createRfcommSocket", new Class[] { int.class });
tmp = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));
Here's the method of interest, which gets run once a BluetoothSocket
is obtained:
public void run() {
setName("ConnectThread" + mSocketType);
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
mmSocket.connect();
} catch (Exception e) {
Log.e(TAG, "Connection to " + mmDevice.getName() + " at "
+ mmDevice.getAddress() + " failed:" + e.getMessage());
// Close the socket
try {
mmSocket.close();
} catch (Exception e2) {
Log.e(TAG, "unable to close() " + mSocketType
+ " socket during connection failure", e2);
}
connectionFailed(e.getMessage());
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothChatService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice, mSocketType);
}
The relevant log entry (printed when the exception is caught while calling connect()
) is this:
11-30 10:23:51.685: E/BluetoothChatService(2870): Connection to
ZYNO-700091 at 00:06:66:42:8E:01 failed:read failed, socket might
closed, read ret: -1
This error used to come up once in a while. I have an aggressive reconnect system - it basically hammers the connection over and over until it connects, and if it were ever to disconnect, it starts hammering it again. So, it kills the connection thread and starts from scratch constantly. I had considered that there might be an issue there - maybe a multithreading one, or maybe in handling the socket cleanup/initialization. However, if that were the case, I'd still expect the first connection attempt to succeed, since that system doesn't kick in until there's a failed connection attempt.
I looked into the source code throwing the exception. The issue seems to be that the underlying InputStream
has no data. Of course, that's not really an answer, just a step towards it. Why would the stream have no data?
I'm trying to keep an open mind about the potential issue. Am I getting the BluetoothSocket
properly? The fact that it was once an intermittent issue and is now nearly constant makes me suspect multithreading, but that's a relatively simple topic in Java compared to C++ - hard to screw up if you know what you're doing. Plus, the majority of this code (in particular, the parts dealing with synchronizing the threads) is straight out of the sample code.
The device on the other end is an embedded Bluetooth device, so there's not much hope of debugging the problem from that end.
UPDATE ===========================
It occurred to me that it might be due to an OS upgrade (I'm running on Galaxy Nexus phones - I have several to test with). So I unpacked a new phone with 4.0.4 and it worked! So then went back and tested on the two original test phones, both running 4.2, expecting the failure I've been seeing all this time. Strangely, now it works on those phones too. I'd like to say I did something to make this work again, but I didn't. I'm still mystified, and now also suspicious that this thing is going to work when I really need it to.
I wonder if there's a possibility that somehow connecting using 4.0.4 could have properly set the state of the server module, making it receptive to the 4.2 devices? Just a shot in the dark, I suppose...
UPDATE 2 ===========================
I've found that unpairing and re-pairing will allow the devices to connect. It's a workaround, but it's better than nothing.
See Question&Answers more detail:
os