0

I am trying to write a small android app (4.4) which searches for several Bluetooth LE devices. Once it has found each device it needs to connect to it and then continually read the RSSI of each device as quickly as it can. I have been trying to get this to work with 6 devices. My current code is as follows:

public class BluetoothGatt extends Activity {
private BluetoothAdapter mBluetoothAdapter;
private static final int REQUEST_ENABLE_BT = 1;
int count = 0;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

    // Initializes Bluetooth adapter.
    final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();
    System.out.println("Adapter: " + mBluetoothAdapter);

    BTScanStart();
}

// Start the Bluetooth Scan
private void BTScanStart() {
    if (mBluetoothAdapter == null) {
        System.out.println("Bluetooth NOT supported. Aborting.");
        return;
    } else {
        if (mBluetoothAdapter.isEnabled()) {
            System.out.println("Bluetooth is enabled...");

            // Starting the device discovery 
            mBluetoothAdapter.startLeScan(mLeScanCallback); 

        }
    }
}

// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { 
    public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
        count++;
        System.out.println("Found " + count + ":" + device + " " + rssi + "db");
        device.connectGatt(null, false, mGattCallback);
        if (count > 5) mBluetoothAdapter.stopLeScan(mLeScanCallback);
    }
};

// Gatt Callback
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            System.out.println(gatt.getDevice() + ": Connected.. ");
            gatt.readRemoteRssi();
        }
        if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            System.out.println(gatt.getDevice() + ": Disconnected.. "); 
        }
    }

    public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
        System.out.println(gatt.getDevice() + " RSSI:" + rssi + "db "); 
        try {
            Thread.sleep(300); 
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        gatt.readRemoteRssi();  

        }
};

}

I am having the following problems:

1) It connects to the devices successfully, but they all disconnect after around 5 seconds with a 'btm_sec_disconnected - Clearing Pending flag' error. Is there a was to keep them connected?

2) The code works fine for a single device, however when using more than one device only one device prints RSSI updates regularly, others update randomly and some don't update at all.

3) I am not sure what context I should supply when calling device.connectGatt .

Thank you in advance for your thoughts!

Chris Hughes
  • 185
  • 2
  • 7
  • I also notice that when calling device.connectGatt(.. six times, the connected callback only fires for the first five... – Chris Hughes Dec 10 '13 at 11:23
  • Yeah I am having issues with repeated connect/disconnects to a singular device. Eventually, the Bluetooth needs reset. I think this is an issue with the LE api. – Lo-Tan Jan 09 '14 at 22:20
  • Check the threads in which your methods are being called from. I suspect your onReadRemoteRssi() is getting called from a Binder Thread and you are still in the handling of the implied BTLE service call. Try posting the gatt.ReadRemoteRssi() onto a handler so that you don't tie up the callback. – Greg Giacovelli May 30 '14 at 21:34

2 Answers2

0

How about just use startLeScan and get rssi?

If your android device filter the ble devices (like nexus 7), you could stopLeScan/ startLeScan repeatedly.

If not(like samsung s4 with android 4.3), just let it scan, onLeScan(...) will give every devices' rssi continuously.

0

For the RSSI issue I will second Sam's answer (https://stackoverflow.com/a/20676785/4248895). It seems that for your use case continuously scanning should be sufficient. You don't want to add the overhead of connection if you can avoid it.

I will answer your other question in that if you do need to connect to these devices for some reason, your stability issues may be related to the fact that you're connecting and scanning simultaneously. Generally speaking, you should not perform any two gatt operations (scanning, connecting, reading, writing, etc.) at the same time.

Community
  • 1
  • 1
Doug Koellmer
  • 407
  • 2
  • 8