Bluetooth LE Gatt connection Android 4.4 to read real-time RSSI

5.8k views Asked by At

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!

2

There are 2 answers

0
Doug Koellmer On BEST ANSWER

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.

0
Sam blood Kao On

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.