I have to calculate the distance of any ble device (not just beacon). I am using the BluetoothLeGatt sample app provided on the devloper android site this is the link http://developer.android.com/downloads/samples/BluetoothLeGatt.zip. I am printing the log in this method
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, final byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
Log.e("scanrecord", Arrays.toString(scanRecord));
}
});
}
};
this is my log
05-05 13:58:35.811 8034-8051/com.example.android.bluetoothlegatt D/BluetoothLeScanner: onScanResult() - ScanResult{mDevice=08:7C:BE:49:7D:9E, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=[0000fee8-0000-1000-8000-00805f9b34fb, 0000fff0-0000-1000-8000-00805f9b34fb], mManufacturerSpecificData={}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=Safety15HA006634], mRssi=-80, mTimestampNanos=2601215802991397}
05-05 13:58:35.816 8034-8034/com.example.android.bluetoothlegatt E/scanrecord: [2, 1, 6, 17, 8, 83, 97, 102, 101, 116, 121, 49, 53, 72, 65, 48, 48, 54, 54, 51, 52, 5, 3, -24, -2, -16, -1, 5, 18, 6, 0, -128, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].
On searching I found the formula to calculate the distance on this link Understanding ibeacon distancing . My problem is how to get the transmission power from the scanRecord
. Also what is the mTxPowerLevel
and how can I get it as this is logged from the android ble classes.
You can't get the RSSI from the scan record, because that record is computed by the beacon, which obviously doesn't know ahead of time what strength you'll receive the transmission with. Luckily, the rssi
parameter gives you the RSSI.
This answer to a related question explains how to get the transmit power, but note that not all devices will give their transmit power. The answer I linked explains that iBeacons in particular use a non-standard manufacturer data to give it, and most general-purpose BLE peripherals just don't include it at all, since it's not useful for anything but ranging. The one you've shown in your log is an example of a device that doesn't give its transmit power: the mTxPowerLevel
shows up as the most negative int
in that case.
If you do have a peripheral that doesn't include its transmit power in the advert, you have to just base your calculation on the RSSI, and calibrate it for the peripheral. That is, you have to measure in the lab the RSSI you get at 1 m with that model of peripheral, and include that information in your app for all the peripherals you want it to work with.
Finally, it's worth noting that you won't get a very accurate range using this method. RSSI varies a lot with radio environment. Holding the phone in a different way, or having your body in between the phone and the peripheral, will all affect the RSSI. Standing in between the phone and the peripheral typically has the same effect as 5–10 m of distance.