I am doing my Master thesis at the moment on WiFi positioning and in order to test my algorithms I needed to collect some data.
To do this I have written a short and very simple program for Android which simply collects the RSSI for all availible access points found by each scan and saves them to file. I have set up a BroadcastReceiver
that listens on the event WifiManager.SCAN_RESULTS_AVAILABLE_ACTION
and I use a Timer
, here called tim, to initiate scans with a WifiManager
, called wifi as follows:
tim.schedule(new TimerTask(){
@Override
public void run(){
wifi.startScan();
}
}, 0, 1000);
The problem I am having now is that the initiated scans don't seem to happen every second even if I succeed in initiating them and every now and then there are other scans initiated from some other app that gets recorded as well.
Is there any easy way to scan on a set interval and not receive the scans initiated by some other app?
The whole app can be found on https://github.com/while/RSSIMiner if it helps in any way.
On devices running Android 9 or lower, when the device is disconnected from Wi-Fi and the screen is off, PNO scans occur at 20 second intervals for the first three scans, then slow down to one scan every 60 seconds for all subsequent scans.
What is Wi-Fi Scan Throttling? Searching the nearby APs is called 'Wi-Fi Scanning'. Wi-Fi Scan Throttling is a feature to restrict the frequency of Wi-Fi scanning for improving the performance and security of the network and prolonging the battery lifetime. This feature is added as default from Android 8.
Turning off Wi-Fi scanning You'll find it at "Security & Location". Under the "Privacy" subhead, tap "Location" then tap "Scanning". You'll have the option to turn off both Wi-Fi and Bluetooth scanning if you like. For all other Android phones, it should be in a similar place.
Is there any easy way to scan on a set interval?
If this doesn't work well, I'm afraid not. From my experience, "hardware related" methods may not work exactly like their definition says. For example, I once created a small app which records your position every X minutes. So I call requestLocationUpdates
with some minTime
parameter. But my phone simply ignores the minTime
value, and I get updates from the GPS as soon as they're available, whcih is not what I wanted. I posted a question about it here, and got this answer, from which we learn that prior to jelly bean, devices may simply ignore this value...
So it may be something similar now. I'd try to run this code on the latest Android version. And I don't understand that much in Wifi, but isn't 1 second a too frequent interval for scans? Perhaps the system doesn't ignore the scan request (So it returns true
) but the hardware does?
Can we ignore the scans initiated by some other app?
As far as I know, it's negative here too. There are no extras contained in the SCAN_RESULTS_AVAILABLE_ACTION
broadcast so you can't know which app initiated the scan.
The best solution will be to defnie your requirements. You can use the ScanResult.timestamp
to determine if you should use this result or not. For example, if you're trying to get the RSSI for each access point each second, you can compare the current BSSID to previous BSSIDs. If the current BSSID was included in a scan result from the last second, you can simply ignore it. Then, it doesn't matter how many results you get.
Another, much more simple soltuion will be to create a boolean called scanInitiated
and set it to true
when starting a scan. When receiving the broacast, use the data only if scanInitiated
is true
, and then set it to false
. This isn't so reliable when the intervals are short, but for long intervals it will work great.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With