0

I am working with a BT Low Energy capable baggage alert device (Link) and have successfully paired it with my Nexus 7.

Following the docs I now would like to connect to the device using the following code:

private BluetoothGattCallback callback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status,
            int newState) {
        Log.i(TAG, "le onConnectionStateChange ["+newState+"]");
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            Log.i(TAG, "le device connected");
            onConnect(gatt.getDevice());
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            Log.i(TAG, "le device disconnected");
            onDisconnect(gatt.getDevice());
        }
    }
    @Override
    public void onServicesDiscovered (BluetoothGatt gatt, int status) {
        Log.i(TAG, "onServicesDiscovered");
    }
};


for (BluetoothDevice device : BluetoothAdapter.getDefaultAdapter().getBondedDevices()) {
    int type = device.getType();

    if (type == BluetoothDevice.DEVICE_TYPE_LE || type == BluetoothDevice.DEVICE_TYPE_DUAL) {
        List<BluetoothDevice> connectedDevices =    
        bluetoothManager.getConnectedDevices(BluetoothProfile.GATT);

        if (!connectedDevices.contains(device)) {
            BluetoothGatt gatt = device.connectGatt(App.getContext(), false, callback);
            gatt.connect();
            gatt.discoverServices();
            List<BluetoothGattService> services = gatt.getServices();
        }
    }
}

However no connection can be initiated. After a while (a few seconds) the connection state changes to BluetoothProfile.STATE_DISCONNECTED - that is even though BluetoothProfile.STATE_CONNECTED was never reached. Am I doing something wrong here?

Prasanth S
  • 3,725
  • 9
  • 43
  • 75
fabian
  • 642
  • 6
  • 18
  • A device can be bonded without being connected. Are the gatt.connect() actually run? It's more common to start scanning, to get a list of available devices instead of assuming it is already connected. You could try that as well. – Vegar Westerlund Feb 17 '14 at 18:23
  • Look closely, it says !connectedDevices.contains(device). The code above goes through the list of bonded devices and tries to establish a connection with those that are currently not connected. The code in the loop is run, and also the callback gets called, however not with BluetoothProfile.STATE_CONNECTED – fabian Feb 17 '14 at 19:48
  • The other thing that might help apart from the comment above is that you don't want to call discoverServices and gattServices is sequence. You want to wait for each callback otherwise getServices will not return anything. I also noticed that you are trying to connect to a tag that normally uses RSSI to detect signal strength and in turn distance, so I am not sure how well defined the GATT server is on it. – Zomb Feb 18 '14 at 05:55
  • @Zomb: You are right about calling, connect/discover in sequence. I did that, because I got no connection and thought that maybe the connection was lazy and needed an action to be carried out, to actually do something. Your last thought has crossed my mind, too. Probably it's not possible to connect to this device. – fabian Feb 18 '14 at 09:25
  • I don't know what the Android API does beneath the BluetoothDevice.connectGatt, but in BLE if you are connected to the device (as in connectedDevices.contains(...)) then there is no other action needed on the BLE link to be able to send Gatt client calls. If you are connected then you are connected. You don't get more connected. – Vegar Westerlund Feb 18 '14 at 18:20
  • @Vegar: I told you, you are not getting it. The exclamation mark "!" asks for devices that are NOT in the list of connected devices. – fabian Feb 19 '14 at 09:26
  • @fabian. Crap, sorry about that. But then it makes even less sense. The fact that you have a bond with the device proves that it will accept connections. There is no way to create a bond without connecting. Do you know the type of the device? Is it DEVICE_TYPE_LE or DEVICE_TYPE_DUAL? Have you tried scanning for the device? It may only be advertising for some time after doing some action on the device itself. – Vegar Westerlund Feb 19 '14 at 18:06
  • @VegarWesterlund can you please look at `http://stackoverflow.com/questions/31048146/getting-state-disconnected-while-connecting-using-bluetooth-smart` as i am facing the same issue – Hunt Jun 25 '15 at 11:35

2 Answers2

2

Well, it turns out, that my code was correct after all. Apparently the Bluetooth Stack had entered a faulty state that could only be recovered by switching the device off and then turning it on again.

FYI: I have Nexus 7 devices. One of the first edition (I think it came out at the end of 2012) and a recent one.

Bluetooth Low Energy does not work on the 2012 Nexus 7. (Not even after switching it off and on again).

Both devices are running Android 4.4.2.

I conclude, that Bluetooth Low Energy does not work on Nexus 7 2012 and is unstable on the current Nexus 7.

How very sad this is.

fabian
  • 642
  • 6
  • 18
  • hi fabian, are u able resolve that issues bez i m facing the same scenario. after 5-6 request its goes into newState == BluetoothProfile.STATE_DISCONNECTED but actually it is connected to device. – chet's Jun 06 '14 at 10:31
  • Unfortunately no. My verdict on this subject was and still is that Bluetooth LE is broken on the Nexus 7 devices. – fabian Jun 06 '14 at 11:15
  • I google it and found that its issue with Android. check this link https://code.google.com/p/android/issues/list?can=2&q=ble&colspec=ID+Type+Status+Owner+Summary+Stars&cells=tiles – chet's Jun 06 '14 at 11:19
0

The problem is that android will only allow 6 maximum bluetooth connections. You must call mBluetoothGatt.close() when the device disconnects

JohnFlux
  • 188
  • 1
  • 5