0
votes

I have TextViews that display the information of iBeacon (e.g. uuid, major, minor, etc.) and a Detect/Stop button to start/stop scanning BLE. When I press the button to start scanning while the iBeacon is turned off, the app displays nothing as expected. However, when I start scanning when the iBeacon is turned on, and then I turn off the iBeacon while scanning, the app still displays the information as if it is still detecting the iBeacon. When the app scans BLE while the beacon is turned on, it gives

D/BluetoothAdapter: onScanResult() - Device=(my device number) RSSI=-49

in the Logcat. When I turn off the beacon while scanning, it gives

D/BluetoothAdapter: startLeScan(): null

and

D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=4.

Is there any way I can detect if iBeacon is turned off using LeScanCallback or anything? I have tried to learn how to do it from Android iBeacon Library, but I still don't know.

Thanks in advance.

2

2 Answers

2
votes

It is impossible to determine that a beacon transmitter has been turned off - all you can do is to say that you have not heard from it in some period of time which is functionally equivalent for your purposes.

That might sound like an academic distinction, but it is not - detection rates in a side-by-side comparison between two phones for the same beacon at the same range can very wildly, from many seconds between detections to multiple detections per second.

Whatever not-heard-from interval you decide to use, make sure you test it on a variety of phones.

Needless to say, given the lack of any universal definition of what "off" means, there is no event callback for it.

0
votes

Which Android API Level are you using? If you are using Android Marshmallow and above you can use ScanSettings.CALLBACK_TYPE_MATCH_LOST. This will send a callback to you ScanCallback#onScanResult(int callbackType, ScanResult result) in case the device you discovered according to your match filter is not in range anymore. In other saying, lost.

Otherwise you can include a HashMap<String,Timer> field (String is for Mac Address) in your class. Update a flag accordingly each time you receive advertisement packet so that when the time is up it checks if the device is in range. If in range, start another timer. Otherwise, it is lost.