Search code examples
androidwifimanagerandroid-9.0-pie

Handle WifiManager#startScan on foreground in Android P


As some information from here and here. We know in Android P

Each foreground app can scan 4 times in a 2-minute period
All background apps combined can scan one time in a 30-minute period

After testing I see, from 5th scan (in 2-minutes), scan is throttled like

WifiService: startScan uid=10085
WifiScanRequestProxy: Scan request from vn.linh.androidwifiscanner throttled

It return old value immediately (in onReceive) without any error or exception. Then I don't know which value is from throttled scan.

Currently, I want to show a popup with countdown in 2 minutes after user scan more than 4 times (after throttled scan).

Of course, I can count the total time user scan in 2 minus manually but I think it is not very effective (eg: if app support work background, we need to check by different way or even in next Android they allow 5 instead of 4,...)

Is there anyone face this problem and found a effective way to solve it?

Here is my current code

class MainActivity : AppCompatActivity() {
    lateinit var wifiManager: WifiManager

    public override fun onCreate(savedInstanceState: Bundle?) {
        ...

        button_scan.setOnClickListener {
            scanWifiNetworks()
        }
        wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
    }

    private fun scanWifiNetworks() {
        registerReceiver(wifiReceiver, IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
        val success = wifiManager.startScan()
        if (!success) {
            scanFailure()
        }
        Toast.makeText(this, "Scanning", Toast.LENGTH_SHORT).show()
    }

    private fun scanFailure() {
        Toast.makeText(this, "Scan failure", Toast.LENGTH_SHORT).show()
    }

    private var wifiReceiver: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            Log.d(TAG, "onReceive " + wifiManager.scanResults.size)
            unregisterReceiver(this)
        }
    }
}

https://github.com/PhanVanLinh/AndroidWifiScanner

Any help or suggestion would be great appreciated.


Solution

  • Well,The closest i could find for your case was boolean flag EXTRA_RESULTS_UPDATED provided in intent received on onReceive.

    According to the docs you would get this false if your app has requested too many times within the short span of time regardless of app being in foreground or background so that solves your problem for writing two different logic for both and counting manually(Whether it's 4 or 5 doesn't matter),but again this is not the only reason you would get this flag false.But i thought it might help.

    You can have a look at official doc about it here: https://developer.android.com/reference/android/net/wifi/WifiManager.html#EXTRA_RESULTS_UPDATED