Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android BluetoothSocket.isConnected always returns false

I am trying to detect whether a bluetooth device is currently connected to an Android device using API 14 or better. It seems like I should be able to use the BluetoothSocket.isConnected() method, but no matter what I've done, so far I just get false back for anything, connected or not.

AndroidManifest includes these lines:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

<!-- Locale 4.x supports API 14 or greater. -->
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />

<uses-feature android:name="android.hardware.bluetooth" />

And the code in question:

protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();

    for (BluetoothDevice device : pairedDevices) {
        Log.i(Constants.LOG_TAG, String.format(Locale.US, "Device: %s connected: %b", device.getName(), isConnected(device))); //$NON-NLS-1$z
    }
}

private boolean isConnected(BluetoothDevice device) {
    BluetoothSocket socket = null;

    // Get a BluetoothSocket for a connection with the given BluetoothDevice
    UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    try {
        socket = device.createRfcommSocketToServiceRecord(SPP_UUID);
    } catch (IOException e) {
        Log.e(Constants.LOG_TAG, e.getMessage()); //$NON-NLS-1$z
        return false;
    }

    Log.i(Constants.LOG_TAG, socket.toString()); //$NON-NLS-1$z

    return socket.isConnected();
}

No errors are thrown, it simply returns "false" 100% of the time. Is there something that I'm not doing right?

like image 276
jkane001 Avatar asked Feb 09 '13 21:02

jkane001


2 Answers

I believe that jkane001 already solved his problem, so I hope this answer will help someone else.

First of all after socket creation

socket = device.createRfcommSocketToServiceRecord(SPP_UUID);

you shall init connection by

socket.connect();

After that you'll be able to check connection state using socket.isConnected()

Since connect() method is not blocking, so immediately after socket may be not connected yet. I suggest to use something like this

while(!socket.isConnected() && trial++ < 3){
    try {
        Thread.sleep(300);
    } catch (Exception e) {}
}

By the way, I found that on some android devices isConnected() always returns false. In such case just try to write something to socket and check if there is no exception.

like image 104
Alex Avatar answered Nov 15 '22 01:11

Alex


Apparently there are devices and/or Android versions where isConnected() is implemented (i.e. the function exists and you can call it), but worse than useless because it always returns false. I have an Alcatel phone in on my desk running Android 4.2.2 which exhibits this behavior.

My code was assuming it was disconnected, and so killed my connection thread and this was driving me crazy for a long time. However, I removed the isConnected() call and assumed it was connected, and everything works fine! I haven't found a better way to check for a valid connection other than waiting for an error and declaring the connection dead. The blocked read() in the thread eventually does fail.

We have reports from the field that sound similar, and 2 of the 2 problem devices for which we know the version are also on 4.2.2. Haven't yet deployed the fix, so not sure if it fixed those cases yet.

like image 22
user1536633 Avatar answered Nov 14 '22 23:11

user1536633