Bluetooth creating socket error - android

I try to create BluetoothServerSocket on Samsung Galaxy Gio.
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothServerSocket tmp = null;
try
{
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME_INSECURE, MY_UUID_INSECURE);
}
catch (IOException e)
{
}
mmServerSocket = tmp;
When I no longer need to use a socket I just close it.
public void cancel()
{
try
{
mmServerSocket.close();
}
catch (IOException e)
{
}
}
In both cases no exceptions are throws. So my problem is. When i try to use 1st pease of code again( without exit from app) Log cat show me exception :
07-07 18:27:44.239: D/BluetoothSocket(13672): create BluetoothSocket: type = 1, fd =-1,
uuid = [null], port = 25
07-07 18:27:44.339: E/BLZ20_WRAPPER(13672): ##### ERROR : __listen_prot_rfcomm: failed
with reason 1#####
That happens till then i don't reboot my phone or TurnOFF\wait\TurnOn my bluetooth. So i think the problem is that BluetoothServerSocket create sockets but he don't close it. Maybe my preconceptions is not right so i want to help.

After a bit of searching, I found this thread whose poster appears to get the same exception (Although it's in Italian, so I don't really understand...). If you scroll down a little, you'll see a java exception thrown for this native exception (__listen_prot_rfcomm: failed with reason 1). The java exception is java.io.IOException: Bad file number.
You can find this problem in many threads online (Android Bluetooth IOException bad file number, Bluetooth failed to get port number). From these 2 we can learn that this problem is device specific. Some devices seem to keep the file descriptor of the socket alive, even after you close it with BluetoothServerSocket.close(), so you can't recreate any sockets using the same settings.
The solution will depend on your application audience:
If you are not planning to publish it in the Play Store/Any other market, you could call BluetoothAdapter.disable(), and then re-enable it. This is very bad user experience, as an application shouldn't disable the bluetooth without asking the users first. But it will solve your problem, because all bluetooth file descriptors will be disposed automatically. So if the only user is you, it's a possible solution.
If you do plan on publishing this, you should find a real solution... It might not be easy, but this is indeed a major problem and it also seems that many devices are affected by it, so you can't publish your app as long as this problem persists.

Related

Android ADK : IO Exception (ENODEV)

I am using Galaxy Nexus (4.2.2) and ADK Board(PIC24F of Microchip Co.) to make an application using Android Open Accessory.
After the following events happen while communicating USB, if it launches my app again, OutputStream.write() throws an IOException(ENODEV) whenever it tries to transmit data to ADK Board.
・App was forcibly killed by Android OS (e.g. Memory shortage, task killer app, etc.)
・App was updated with new version.
It comes to succeed after USB detached once.
code:
public void openAccessory(UsbAccessory accessory) {
ParcelFileDescriptor p = mUsbManager.openAccessory(accessory);
if (p == null) { return;}
else {mFileDescriptor = p;}
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
if (fd == null) {return;}
mOutputStream = new FileOutputStream(fd);
if (isSendSuccess()) {
mInputStream = new FileInputStream(fd);
}
}
private boolean isSendSuccess() {
final byte[] test = new byte[]{0x01,02};
for (int i=0; i<2; i++) { //send test
try {
mOutputStream.write(test);
return true;
} catch (IOException e) {
e.printStackTrace(); //throw ENODEV after app is forced kill.
}
}
return false;
}
error log:
W/System.err(17198): java.io.IOException: write failed: ENODEV (No such device)
W/System.err(17198): at libcore.io.IoBridge.write(IoBridge.java:462)
W/System.err(17198): at java.io.FileOutputStream.write(FileOutputStream.java:187)
・・・・・・
W/System.err(17198): Caused by: libcore.io.ErrnoException: write failed: ENODEV (No such device)
W/System.err(17198): at libcore.io.Posix.writeBytes(Native Method)
W/System.err(17198): at libcore.io.Posix.write(Posix.java:178)
W/System.err(17198): at libcore.io.BlockGuardOs.write(BlockGuardOs.java:191)
W/System.err(17198): at libcore.io.IoBridge.write(IoBridge.java:457)
W/System.err(17198): ... 23 more
codicil:
I know that there is an existing problem, such as:
http://code.google.com/p/android/issues/detail?id=20545
So, I regularly send data from ADK Board to my app, and it works fine.
However, the above problem occurs.
Could you advise if there is a workaround ?
Thanks.
This is a known bug in UsbManager, for several years already:
Issue 20545: Unable to cleanly close USB accessory FileInputStream
A fix developed but haven't merged into Android trunk yet:
Issue 61390: Potential source code fixes for UsbAccessory not unbinding cleanly
Also you may want to look at this discussion: Proper way to close a USB accessory connection to workaround ideas in some use cases.
I'm working with a customized Android ROM (CyanogenMod) so I'll probably try to apply the fix from 61390. I did a lot of testing trying to workaround it myself, but I was not able to get a stable solution. I was considering to use libusb port instead: https://github.com/OpenNI/OpenNI2/tree/master/ThirdParty/PSCommon/XnLib/ThirdParty/libusb-1.0.9-Android (from https://stackoverflow.com/a/16234205/1028256, you can upvote it there), it is told to work even on not rooted phones (I haven't tried myself), and it supports async mode, so one can avoid blocking thread in Java. But you will have to use JNI, still it's much better than any non-stable solution IMHO.

IsoDep .connect throws "e=null"

This sounds weird, I know.
I am developing an Android app using NFC, the app reads a tag from a samrtcard using IsoDep APDU commands, everything usually works but sometimes it fails, and keep on failing in the followed executions, when it fails it occurs when connecting the tag, the tag has its "mConnectedValue = -1", which means no technology connected but the followed code is executed
card = IsoDep.get(tag);
card.setTimeout(20000);
card.connect();
connect() throws ans excepcion, the exception is catch by this code:
} catch (IOException e) {
...
}
If "e" is inspected with eclipse shows e=null, but the code inside the catch is executed, anyone can explain why e=null? The code above is inside a loop, and followed executions keep on returning that "exception" e=null.
Thank you very much!
Fixed, well, actually the "e=null" still the same, sometimes it throws "IOException e = null" and sometimes just "e= null", in both cases the error is caught by the same code, it might be some kind of bug.
I also solved the connection problem, it was device's fault, the chip was not powerful enough to supply energy to the smartcard, for reading and writing was ok, but when the card make some operations it isn't enough, just moving the phone a little bit upwards solved the problem.
Thanks!

socket.connect causes "read failed socket might closed" only on Android 4.2.1 on Nexus [duplicate]

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.
Jellybean has a completely different Bluetooth stack, so version differences could certainly be triggering something, but that in itself wouldn't explain why it stays working or not-working after connecting with an older device. Could it be to do with pairing? If it happens again, try unpairing from the device and pairing again.
I know this is kind of an old question. But as I was not able to find any solution on the web, here is a workaround I recently have created: IOException: read failed, socket might closed - Bluetooth on Android 4.3
In my case it was due to bad UUID in createRfcommSocketToServiceRecord() function.
I want to connect to SPP serial profile in raspberry pi 3 and I used this UUID:
private static final UUID MY_UUID_SECURE =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
I found somewhere in android documents' page for SPP.
I had the same problem while connecting to the arduino via bluetooth module.The problem only arised while connecting with arduino as it connected smoothly with another android phone bluetooth.
What worked for me was changing the UUID string..

BluetoothSocket.connect() throwing exception "read failed"

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.
Jellybean has a completely different Bluetooth stack, so version differences could certainly be triggering something, but that in itself wouldn't explain why it stays working or not-working after connecting with an older device. Could it be to do with pairing? If it happens again, try unpairing from the device and pairing again.
I know this is kind of an old question. But as I was not able to find any solution on the web, here is a workaround I recently have created: IOException: read failed, socket might closed - Bluetooth on Android 4.3
In my case it was due to bad UUID in createRfcommSocketToServiceRecord() function.
I want to connect to SPP serial profile in raspberry pi 3 and I used this UUID:
private static final UUID MY_UUID_SECURE =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
I found somewhere in android documents' page for SPP.
I had the same problem while connecting to the arduino via bluetooth module.The problem only arised while connecting with arduino as it connected smoothly with another android phone bluetooth.
What worked for me was changing the UUID string..

RFCOMM_CreateConnection - already opened state:2, RFC state:4, MCB state:5

I´m writing an android app that connects to a device through bluetooth using RFCOMM. I use the BluetoothChat example as basis for establishing a connection and everything works perfectly most of the time.
However, sometimes I cannot reconnect due to a message that the socket is already open:
RFCOMM_CreateConnection - already opened state:2, RFC state:4, MCB
state:5
This tends to happen if I connect to the device, close the app (call onDestroy()), reopen it and try to connect again, which results in the above.
I use this method for connecting in the ConnectThread(ref.BluetoothChat example):
Method m = device.getClass().getMethod("createRfcommSocket",new Class[] {int.class });
tmp = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));
mmSocket = tmp;
The only thing that resolves this problem is turning off/on the Bluetooth of the Android phone.
This leads me to believe that the socket is not being closed in onDestroy() but still I´m calling on closing all threads as shown in the before mentioned example.
Any ideas would be appreciated.
I stumbled upon this one too, and here is the answer I found:
This error may happen, if you open and close a bluetooth socket connection multiple times.
Solution
Starting from API Level 14 there is a Method in BluetoothSocket called isConected(), which returns true, if this socket is already connected and false otherwise, here the original excerpt from the API:
Get the connection status of this socket, ie, whether there is an
active connection with remote device.
For API levels < 14 you can work around this issue by putting your Bluetooth Handling Thread to sleep after closing the connection - 1000 ms should be enough, here is an example (btDevice is of the type BluetoothDevice and has been initialized prior to the code snippet below):
try {
//Open the socket to an SPP device (UUID taken from Android API for createRfcommSocketToServiceRecord)
BluetoothSocket btSocket = btDevice.createRfcommSocketToServiceRecord("00001101-0000-1000-8000-00805F9B34FB");
//Connect to the socket
btSocket.connect();
//Close the socket
btSocket.close();
//Sleep time of 1000ms after closing the socket
SystemClock.sleep(POST_RESET_DELAY);
} catch (Throwable e) {
// Log error message
}
P.s. Instead of SystemClock.sleep you can also use Thread.sleep - however the SystemCock's sleep can't be interrupted, whereas the Thread.sleep can be interrupted, so it depends on your use-case which option better suits your purpose.
Source: Louis A. Prado

Categories

Resources