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
votes
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 tracker
– Jan 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.