2
votes

I can scan for Bluetooth LE devices through startLeScan or via the new getBluetoothLeScanner and that works fine. However even though it keeps on scanning it never detects the same device twice. That's unfortunate because I would like to receive events when the rssi of a beacon changes. Does Android support that?

2
Related: stackoverflow.com/questions/27111309/… There doesn't seem to be a way to get updates on RSSI without an established connection. In the link a scan is started/stopped periodically.cygery
I found this: "On Nexus 4 and Nexus 7 the callback is invoked either when a new device has been found or when the sensor is non-connectable. In the later case you get RSSI updates constantly." - From Android bug trackerJan Jongboom

2 Answers

1
votes

Implement a BluetoothGattCallback and override the onReadRemoteRssi method.

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            String intentAction;
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                broadcastUpdate(intentAction);

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                broadcastUpdate(intentAction);
            }
        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            super.onReadRemoteRssi(gatt, rssi, status);
            // use rssi value here
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
            } else {
                Log.w(TAG, "onServicesDiscovered received: " + status);
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic,
                                         int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }
    };
1
votes

Two solutions which I used.

1) Make a connection, call readRemoteRssi(); of gatt and override onReadRemoteRssi, and have your own check to see if the RSSI is changed.

2) StrartLEScan every 20 Sec(20 sec is enough time to receive new advertisement packets) and have a check on onLeScan callback to see if the device is found, if yes then compare RSSI.

RSSI is the value which your device(scanner) derives.

Also if you have code for GATT STACK, you will get onLEScan called many times for single device, it is GattService which truncate duplicate results.