socket might be closed android error on android 6.0 only - android

I am using a bluetooth library I found online called multibluetooth to connect a bunch of clients. I am testing with 2 android phones, 1 is running 5.0 and the other 6.0. Running a server on the 6.0 phone and a client on the 5.0 phone works but when I reverse the roles I get this error:
04-07 00:27:03.507 7499-8393/com.ramimartin.sample.multibluetooth W/BT: Fallback failed. Cancelling.
java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:900)
at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:859)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:535)
at com.ramimartin.multibluetooth.bluetooth.client.BluetoothConnector$FallbackBluetoothSocket.connect(BluetoothConnector.java:203)
at com.ramimartin.multibluetooth.bluetooth.client.BluetoothConnector.connect(BluetoothConnector.java:59)
at com.ramimartin.multibluetooth.bluetooth.client.BluetoothClient.run(BluetoothClient.java:54)
at java.lang.Thread.run(Thread.java:818)
Here is the part where I am getting the error:
public BluetoothSocketWrapper connect() throws IOException {
boolean success = false;
while (selectSocket()) {
adapter.cancelDiscovery();
try {
bluetoothSocket.connect();
success = true;
break;
} catch (IOException e) {
//try the fallback
try {
bluetoothSocket = new FallbackBluetoothSocket(bluetoothSocket.getUnderlyingSocket());
Thread.sleep(500);
bluetoothSocket.connect();
success = true;
break;
} catch (FallbackException e1) {
Log.w("BT", "Could not initialize FallbackBluetoothSocket classes.", e);
} catch (InterruptedException e1) {
Log.w("BT", e1.getMessage(), e1);
} catch (IOException e1) {
Log.w("BT", "Fallback failed. Cancelling.", e1);
}
}
}
if (!success) {
throw new IOException("===> Could not connect to device: " + device.getAddress());
}
return bluetoothSocket;
}
Thank you in advance.

In case the disconnection happens while you leave the devices on sleep, this could be related with the Doze mode.
You can find more info at https://developer.android.com/training/monitoring-device-state/doze-standby.html .
Also feel free to ask me for more details.

Related

Android XMPPTCPConnection: Machine is not on the network

While on Wifi, XMPPTCPConnection in our Android app is occasionally throwing "SocketException: Machine is not on the network" even though the phone does have net connection. When users turns off Wifi and turns it on again, the app is able to connect instantly.
When this exception occurs, the XMPPTCPConnection object is disconnected and set to NULL and created afresh before attempting reconnection. Yet it does not help. Below is the code snippet.
try {
if (null != connection)
connection.disconnect();
} catch (Exception e) {
}
connection = null;
XMPPTCPConnectionConfiguration connConfig = createConfiguration();
if (null != connConfig)
{
connection = new XMPPTCPConnection(connConfig);
try {
connection.connect();
} catch (StackOverflowError e) {
e.printStackTrace();
} catch (XMPPException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
Please let me know how to fix this issue. Appreciate your help.
This is the stack trace.
org.jivesoftware.smack.SmackException$ConnectionException: The following addresses failed: '.com:5223' failed because java.net.SocketException: Machine is not on the network
at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectUsingConfiguration(XMPPTCPConnection.java:596)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection.java:830)
at org.jivesoftware.smack.AbstractXMPPConnection.connect(AbstractXMPPConnection.java:360)
at com.sarkms.cclib.XMPPConnLib.connectToChatServer(XMPPConnLib.java:184)
at com.sarkms.cclib.XMPPConnHelper.connectToChatServer(XMPPConnHelper.java:331)
at com.sarkms.cclib.XMPPConnHelper.LoginToChatServer(XMPPConnHelper.java:383)
at com.sarkms.cclib.ConnChkRun.runConnectionCheck(ConnChkRun.java:83)
at com.sarkms.cclib.ops.Connection.runConnection(Connection.java:142)
at com.sarkms.cclib.MessageService$1.run(MessageService.java:39)

Android: exception when disconnecting from bluetooth device

I'm looking for a way to gracefully disconnect from a Bluetooth device. I used the BluetoothChat sample and the problem is that when you intend to disconnect you simply call socket.close() from the cancel() method, but then the IntputStream.read() will inevitably throw an exception.
I need this mainly because it acts as a "lost connection" failsafe as well, so when I try to disconnect I get two signals: graceful disconnection followed by lost connection signal.
Basically what I'm trying to do is not to throw an exception in a method that will inevitably throw one:
while(true)
{
try
{
bytes = 0;
while((ch = (byte) inStream.read()) != '\0')
{
buffer[bytes++] = ch;
}
String msg = new String(buffer, "UTF-8").substring(0, bytes);
Log.v(TAG, "Read: " + msg);
}
catch(IOException e)
{
Log.e(TAG, "Failed to read");
// Inform the parent of failed connection
connectionEnd(STATE_LOST);
break;
}
}
And the extremely egoistic cancel():
public void cancel()
{
try
{
socket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
EDIT
This is the error code I get when I e.printStackTrace(); in catch:
09-06 13:05:58.557: W/System.err(32696): java.io.IOException: Operation Canceled
09-06 13:05:58.557: W/System.err(32696): at android.bluetooth.BluetoothSocket.readNative(Native Method)
09-06 13:05:58.557: W/System.err(32696): at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:333)
09-06 13:05:58.557: W/System.err(32696): at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:60)
09-06 13:05:58.557: W/System.err(32696): at com.bluetooth.BluetoothRemoteControlApp$ConnectedThread.run(BluetoothRemoteControlApp.java:368)
Try this:
Suppose you have out object of OutputStream and in object of InputStream, Then
inside your cancel close the connection like this:
public void cancel()
{
if(socket != null)
{
try {
out.close();
in.close();
socket.getOutputStream().close();
socket.close();
socket = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Hope this help you
Solution: it's not perfect, but since there's no way of stopping the exception I made a disconnecting condidition:
catch(IOException e)
{
if(!disconnecting)
{
Log.e(TAG, "Failed to read");
e.printStackTrace();
// Inform the parent of failed connection
connectionEnd(STATE_LOST);
}
break;
}
disconnecting is set to true before calling the cancel() method. I'm not happy with it but it's not that ugly. I'm just not satisfied with the way the Bluetooth disconnection is handled (it works or it breaks).

Android Bluetooth socket connection takes too long and eventually failed

I am trying to connect a bluetooth device from the Android phone. In most cases, the connection is successful.
I am making the socket connection using the following code:
if (isUsingHtcTypeConnectionScheme) {
try {
if (LOG_ENABLED) Log.d(TAG,"connecting to SPP with createRfcommSocket");
Method m = mRemoteDevice.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
tmpSocket = (BluetoothSocket)m.invoke(mRemoteDevice, 1); // may be from 1 to 3
} catch (java.lang.NoSuchMethodException e){
Log.e(TAG, "java.lang.NoSuchMethodException!!!", e);
} catch ( java.lang.IllegalAccessException e ){
Log.e(TAG, "java.lang.IllegalAccessException!!!", e);
} catch ( java.lang.reflect.InvocationTargetException e ){
Log.e(TAG, "java.lang.InvocationTargetException!!!", e);
}
}
if (tmpSocket == null) {
try {
if (LOG_ENABLED) Log.d(TAG,"connecting to SPP with createRfcommSocketToServiceRecord");
tmpSocket = mRemoteDevice.createRfcommSocketToServiceRecord(uuid); // Get a BluetoothSocket for a connection with the given BluetoothDevice
} catch (IOException e) {
Log.e(TAG, "socket create failed", e);
}
}
mBtSocket = tmpSocket;
try {
mBtSocket.connect();
} catch (IOException e) {
connectionFailed();
setState(STATE_IDLE);
return;
}
And if the other device's bluetooth is not on, it will throw the IOException in 2-3 seconds, this is the normal behavior.
But sometimes the connection takes 20-30 seconds and eventually failed, and the other device's bluetooth is on.
I am wondering why this happens, if the phone cannot connect to device, it should throw IOException in 2-3 seconds. But now is taking 20-30 seconds to throw the IOException. (And the other device is ready for connection actually)
I tested on several Android phones and also have this problem, so may not be related to specific phone.
Any ideas?
Thanks!

Android 2.1 How to disconnect a connected bt device

I have referenced the link:
Disconnect a bluetooth socket in Android
but still it doesn't work for me. always through an exception at BluetoothSocket::connect()
My case is that if User has paired and connected a remote bt device via the phone, how can I programmatically disconnect it??
I got a hunch that if I want the connection to be disconnected I should close the input, output stream then perform BluetoothSocket close. And I can't find anywhere to get the socket on the connected device. the API createRfcommSocketToServiceRecord is to create a socket. Thank you!
PS, the remote bt device is headset
follow the below procedure
if (mmSocket != null) { try { mmSocket.close(); } catch (Exception e) { Log.e("Exception", "while closing socket"+e.toString()); } mmSocket = null; }
if (mmOutStream != null) { try { mmOutStream.close(); } catch (Exception e) { Log.e("Exception", "while closing outstream"+e.toString()); } mmOutStream = null; }
if (mmInStream != null) { try { mmInStream.close(); } catch (Exception e) { Log.e("Exception", "while closing inputstream"+e.toString());} mmInStream = null; }

Android connect to Blackberry 655+ bluetooth headset

I'm trying to write a test app which connects to BlackBerry 655+ bluetooth headset. Basically what i want to do in this app is connect to the headset and catch button pressures on it. I think that could be done by reading the socket's inputstream. Anyway, i get some errors right when i try to connect to the socket. Here's the code:
BluetoothSocket tmp = null;
try {
tmp = mDevice.createRfcommSocketToServiceRecord(
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
} catch(IOException e) {}
mSocket = tmp;
mBtAdapter.cancelDiscovery();
try {
mSocket.connect(); // THIS ONE GIVES A "Service discovery failed" exception
} catch (IOException e1) {
Method m = null;
try {
m = mDevice.getClass().getMethod(
"createRfcommSocket", new Class[] {int.class});
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
tmp = (BluetoothSocket) m.invoke(mDevice, 1);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
mSocket = tmp;
try {
mSocket.connect(); // THIS ONE GIVES A "Connection refused" EXCEPTION
} catch (IOException e) {
e.printStackTrace();
}
}
What am i doing wrong? I already tried different ports in the m.invoke(mDevice, X) instruction but it always gives "Connection refused"
I worked with Bluetooth before but with python and Java ME so I understand the basics. I don't know much about the android API though.
Where did you get the UUID code from? That could be one of the reasons for the Service discovery failed.
Each bluetooth device may have several services each of them associated to one port (or channel). If you are running ubuntu try using the hci tools to know to which channel connect or which service to search for.
Here you have an official list with UUIDs from Bluetooth SIG. For Headset Profile the UUID is 0x1108, the UUID used by you it is Base Universally Unique Identifier and it is used for SDP.

Categories

Resources