One part of my application connects to a device through Bluetooth and normally works fine but occasionally it won't connect and I get the following error
03-11 10:29:20.328: E/BluetoothComService(8059): accept() failed
03-11 10:29:20.328: E/BluetoothComService(8059): java.io.IOException: Operation Canceled
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothSocket.acceptNative(Native Method)
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothSocket.accept(BluetoothSocket.java:316)
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothServerSocket.accept(BluetoothServerSocket.java:105)
03-11 10:29:20.328: E/BluetoothComService(8059): at android.bluetooth.BluetoothServerSocket.accept(BluetoothServerSocket.java:91)
03-11 10:29:20.328: E/BluetoothComService(8059): at com.mypackage.name.bluetooth.BluetoothService$AcceptThread.run(BluetoothService.java:298)
This is the line where I get the exception
socket = mmServerSocket.accept();
And this is the complete AcceptThread
private class AcceptThread extends Thread {
// The local server socket
private BluetoothServerSocket mmServerSocket;
public boolean successInit = false;
public AcceptThread() {
closeAllConnections();
/*
* if(mmServerSocket != null) { try { mmServerSocket.close(); } catch
* (IOException e) { e.printStackTrace(); } }
*/
BluetoothServerSocket tmp = null;
// Create a new listening server socket
while (!successInit) {
try {
tmp = mAdapter
.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
successInit = true;
} catch (Exception e) {
successInit = false;
}
}
/*
* try { tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME,
* MY_UUID); successInit= true; } catch (IOException e) { Log.e(TAG,
* "listen() failed", e); tmp = null; successInit = false; }
*/
mmServerSocket = tmp;
}
public void run() {
if (D)
Log.d(TAG, "BEGIN mAcceptThread" + this);
setName("AcceptThread");
BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (mState != STATE_CONNECTED) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mAdapter.cancelDiscovery();
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "accept() failed", e);
Log.e("Error", "This isn't connecting");
break;
}
// If a connection was accepted
if (socket != null) {
synchronized (BluetoothService.this) {
switch (mState) {
case STATE_LISTEN:
case STATE_CONNECTING:
// Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice());
break;
case STATE_NONE:
case STATE_CONNECTED:
// Either not ready or already connected. Terminate new
// socket.
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
if (D)
Log.i(TAG, "END mAcceptThread");
}
public void cancel() {
if (D)
Log.d(TAG, "cancel " + this);
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of server failed", e);
}
}
}
Here is the function I call at the beginning of AcceptThread
in hopes to close everything to restart it
public void closeAllConnections() {
if (mmInStream != null) {
try {mmInStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmOutStream != null) {
try {mmOutStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmSocket != null) {
try {
mmSocket.close();
//mmSocket.connect();
}
catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
I've read through the Bluetooth Docs and SO questions but I haven't found anything that works for me and it gets a bit confusing for me as this is my first time connecting through BT.
Note
The only "fix" I have found when this happens is to turn off the BT adapter, force close the program, restart BT adapter and restart app, which is not good for obvious reasons. I tried restarting the adapter programmatically but I still can't connect.
Can anyone see what might be wrong in my BlutoothService class, which is where AcceptThread
is located? Or how I would go about resolving this issue? Thanks!
It does, in fact, seem like the connection is sometimes closed on one Thread
and trying to reconnect on another. The problem is that I can't figure out what would cause it to try and connect on a separate Thread
or how to fix it when this happens.
The only way I can successfully reproduce this is if my BT device is turned off then I turn the BT adapter off. When I turn everything back on then I get the exception and cannot connect. I have customers that it happens to randomly and periodically so I'm hoping the issues are related.
Well, part of my problem was a hardware issue that was found out to be a problem on the third-party manufacturers end. They're firmware wasn't quite right and when it was reading the BT address, it was occasionally being corrupted.
On the software side, it was running the AcceptThread
in two separate Threads
periodically. What I did to fix that was to create a function to close the socket and input/output streams...
public void closeAllConnections()
{
if (mmInStream != null)
{
try {mmInStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmOutStream != null)
{
try {mmOutStream.close();}
catch (Exception e){Log.e(TAG, "close() of connect socket failed", e);}
}
if (mmSocket != null)
{
try {
mmSocket.close();
Log.e("TAG", "close() of connect socket successfu;");
} catch (IOException e) {
Log.e("TAG", "close() of connect socket failed", e);}
}
Then in the BluetoothCom
class, I noticed it wasn't always checking for the BT object to be null
before trying to restart the service.
private void setupService() {
// Initialize the BluetoothChatService to perform bluetooth connections
if((mChatService != null) && (mChatService.getState() != 0)) {
mChatService.stop();
}
// I didn't have this so it would always start a new instance of the Service
if (mChatService == null)
mChatService = new BluetoothService(mHandler);
mChatService.start();
}
This seems to have helped and I no longer have those problems. However, now testing on the Samsung Galaxy Tab 4 and I am once again having connection issues but only on this device. Maybe this information can help someone and I will update my answer if I figure anything else out with the new problem.
Note: As stated above, this Bluetooth app uses modified code from Android's BluetoothChat app.
Also, I have read (and noticed) that different manufacturers implement the BT stack differently which can lead to headaches (at least if yo don't know enough about it).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With