https://lishiwen4.github.io/wifi/android-wifi-scan-interval
1.android wifi 循環掃描
在android系統中, 在不同的場景下, 不同的功能模塊會發起循環掃描
大部分掃描功能需要調用WPAS的接口來完成, 可先閱讀 “WPAS” 分類中的 “WPAS 中的循環掃描”
2. 亮屏時Wifi Settings界面的掃描
只要打開wifi, 進入wifi settings界面, 無論是否連接了AP, 都會開始定時掃描
相關源碼爲 “pacakes/app/Settings/src/com/android/settings/wifi/WifiSettings.java” Wifi Setting 中由 class Scanner來負責發起掃描, calss Scaner繼承了Handlerl來實現定時掃描:
- 延時向自己發送一個空message
- 接收到message後, 立即調用WifiManager執行一次掃描, 然後再次延時向自己發送空message
- 向自己發送空message的延時值即爲掃描的間隔, 默認爲10s (int WIFI_RESCAN_INTERVAL_MS = 10 * 1000;)
其向自己延時(WIFI_RESCAN_INTERVAL_MS)發送message, 接收到mesage後, 執行一次掃描來實現定時掃描, 其提供了3個接口
Scanner.pause() //移除還未被髮送的空message, 中止定時掃描
Scanner.resume() //向自己發送一個空的message, 恢復掃描
Scanner.forceScan() //移除還未被髮送的的空message, 並立即發送一個空message, 導致馬上進行一次掃描
- 在wifi Settings的onpause()階段, 中止定時掃描
- 在wifi Settings的onresume()階段, 恢復定時掃描
- 點擊wifi Settings菜單的scan選項, 則進行一次強制掃描
- 關閉wifi會中止定時掃描
- 打開wifi會恢復定時掃描
- 在wifi 處於DHCP狀態時, 中止定時掃描, 變爲其它狀態後再恢復定時掃描
3.亮屏時 wpa_supplicant 的週期掃描
在亮屏, 未連接wifi, WPAS中保存了AP的情況下,WPAS會週期掃描,android上調整間隔爲15s, 可在 frameworks/base/core/res/res/values/config.xml 文件中修改。
<integer translatable="false" name="config_wifi_supplicant_scan_interval">15000</integer>
4. 滅屏時 PNO 掃描
如果未連接AP, 但是保存有AP, 在滅屏後, 會開啓PNO掃描, 標準的PNO掃描機制爲
- 以10秒時間間隔掃描6次
- 以20秒掃描間隔掃描6次
- 以40秒時間間隔掃描6次
- 以80秒時間間隔掃描6次
- 以160秒時間間隔掃描6次
- 以後將以320秒時間間隔進行掃描
5. autojoin 掃描
如果打開了autojoin機制, 且保存了AP, 無論是亮屏還是滅屏, autojoin會週期掃描, 間隔爲10s
6. batch scan
batch scan 通過從applicantion offloading scan 到 wifi firmware 來達到節省電力的目標, applicantion可以請求wifi firmware在指定的時間間隔內發起指定次數的掃描, wifi firmware根據限定的頻率持續進行掃描並且緩存掃描結果, 定期將掃描結果返回給 ACPU
batch scan 需要wifi driver 和 wifi firmware支持, wifiManager提供了接口來使用batch scan,例如:
- requestBatchedScan()
- isBatchedScanSupported()
- stopBatchedScan()
- getBatchedScanResults()
- pollBatchedScan()
batch scan主要應用於wifi 輔助定位
Android關閉屏幕,但不休眠
https://blog.csdn.net/curly_x/article/details/114732270
updatePowerStateLocked()方法
private void updatePowerStateLocked() {
...
//updateSuspendBlockerLocked(); //註釋掉這一行就可以了
WiFi之PNO功能
PNO 即Preferred Network Offload,用於系統在休眠的時候連接WiFi
此功能是在Android3.1加入的
代碼:
當屏幕狀態有變化的時候,會調用handleScreenStateChanged(),如果pno功能有enable,就會配置pno,然後再scan.
private void handleScreenStateChanged(boolean screenOn)
{
//亮屏的情況
if (screenOn) {
enableBackgroundScan(false);
setScanAlarm(false);
clearBlacklist();
fullBandConnectedTimeIntervalMilli
= mWifiConfigStore.wifiAssociatedShortScanIntervalMilli.get();
// In either Disconnectedstate or ConnectedState,
// start the scan alarm so as to enable autojoin
//如果當前是連接着的
if (getCurrentState() == mConnectedState
&& allowFullBandScanAndAssociated()) {
//PNO功能是否開啓了
★★★refs:
Wi-Fi PNO掃描流程(Android P)
https://cloud.tencent.com/developer/article/1662008
Android 8 wifi 掃描時間間隔
https://www.cnblogs.com/helloworldtoyou/p/9667229.html
WiFi的幾種掃描類型
https://blog.csdn.net/weixin_40588186/article/details/132997514
WiFi的掃描用於發現附近可用網絡。一般可以分爲兩種主要類型: 主動掃描(active scan) 和 被動掃描(passive scan)。
主被動掃描
-
主動掃描 (Active Scan)
發起主動掃描時,WiFi設備會主動發送
Probe Request
幀,這些請求會廣播到附近所有可見的WiFi AP,AP會以Probe Response
響應,並在響應幀內提供網絡信息。由於WiFi有很多信道,所以主動掃描時,一般會在所有頻段中不停切換以在不同的信道上掃描,大體流程如下:
-
選擇某個信道: 初始信道通常是當前連接的信道或者上一次成功連接的信道。
選定信道後,並不會立即進行探測,而是要等候接收到一個數據幀(indication of an imcoming frame)或者ProbeDelay 計時器 到期。
如果在ProbeDelay時間內接收到了數據幀,證明該信道有人在使用,因此可以立即進行
Probe Request
.當然,ProbeDelay計時器到期後,也會立即發送
Probe Request
,主要是不能一直等下去。ProbeDelay計時器
的主要作用是控制掃描頻率,同時也能節省電池壽命。 -
發送
Probe Request
-
等待
Probe Response
這裏涉及到等待時間的問題,究竟主動掃描時需要在每個信道上停留多長時間。這裏涉及到兩個時間相關的參數: MinChannelTime 和 MaxChannelTime。
至少需要等待MinChannelTime的時間。這段時間內如果介質並不忙碌,表示無網絡存在,因此可以跳到下一個信道;否則繼續等待,直到MaxChannelTime。
-
-
被動掃描 (Passive Scan)
被動掃描時,WiFi設備不會發送
Probe Request
,而只是監聽無線信道上的數據包。它記錄下附近的 AP 發送的 Beacon 幀(包含網絡信息)。設備會首先選擇一個初始信道,然後依次選擇不同的信道進行監聽。
AP會週期性的廣播beacon幀,包含了網絡的信息:如網絡的SSID、信號強度、加密類型等。
Passive Scan時也需要確定在每個信道上停留的時間,這個時間通常稱爲"channel dwell time"(信道停留時間)或 “channel scan interval”(信道掃描間隔),可以是固定的,也可以是動態的:
-
固定信道停留時間
設備可能在每個信道上停留一定的時間,例如 100 毫秒,然後切換到下一個信道。這種方式簡單且容易實現,但可能無法適應不同環境的需求
-
自適應信道停留時間
這種策略可能會根據環境中的網絡密度、信道負載和其他因素來動態調整信道停留時間。例如,在擁擠的信道上,設備可能會停留更長時間以確保檢測到 Beacon 幀。
-
不管是被動掃描還是主動掃描,都會有一個信道列表,設備需要在這些信道上執行掃描,那麼我們其實也可以僅掃描感興趣的信道,而不是全信道掃描。這裏就引出來兩個概念: **單通道掃描(Single-Channel Scanning)**和 全通道掃描(Full-Channel Scanning),很容易理解,就不解釋了。
PNO 掃描
對於移動設備,另一個比較重要的概念是PNO掃描(Preferred Network Offload): 它也是主動掃描的一種。
PNO(Preferred Network Offload)掃描是一種用於降低移動設備功耗的 Wi-Fi 掃描技術,它允許設備在後臺智能地尋找和連接首選的 Wi-Fi 網絡。而不是去全頻道的搜索。如果搜索到首選網絡,一般會自動連接(auto-join).
Android平臺上,在以下幾種情況下會發起新的PNO掃描
- 設備移動狀態發生變化
根據設備的移動狀態(device mobility state)來調整PNO掃描的時間間隔. 詳情參考WifiConnectivityManager.java
的 setDeviceMobilityState()
當移動狀態發生改變時,並不會主動發起PNO掃描;只會修改當前PNO掃描的間隔時間。
當前默認配置的間隔時間如下:
移動狀態(config_wifiMovingPnoScanIntervalMillis): 20s
靜止狀態(config_wifiStationaryPnoScanIntervalMillis): 60s
- 外部主動發起PNO掃描
setExternalPnoScanRequest 外部主動發起PNO掃描,可設置的參數有:
List<WifiSsid> ssids; // ssid列表
int[] frequencies; // 信道列表
Executor executor; // 回調的executor
PnoScanResultsCallback callback; // 回調接口
clearExternalPnoScanRequest
上面兩個接口僅支持Android T,目前無人使用。
- ConnectivityScan
實際上,只有在 Screen OFF 並且 WiFi Disconnected 的情況下系統纔會主動會發起PNO掃描,如果設備移動狀態發生變化只可能修改PNO掃描的間隔時間。
而發起PNO掃描就在WifiConnectivityManager
的startConnectivityScan()
private void startConnectivityScan(boolean scanImmediately) {
// ... ...
if (mScreenOn) {
startPeriodicScan(scanImmediately);
} else {
if (mWifiState == WIFI_STATE_DISCONNECTED && !mPnoScanStarted) {
startDisconnectedPnoScan();
}
}
}
前後臺掃描
另外,還有Foreground Scan
和 Background Scan
兩個概念:
-
Foreground Scan
一般指當前未連接到任何AP 的情況下發起的掃描
-
Background Scan
一般指當前已經連接到某個AP,但是爲了保證更好的網絡質量,某些情況發起的掃描叫background scan。
具體是前臺掃描還是後臺掃描,通常是firmware決定的,跟上層沒什麼關係。
乍一看,Foreground Scan 和 Background Scan 除了使用場景差異,具體的掃描動作並沒有不同。其實這裏的細節都是由wifichip處理(firmware)。Foreground Scan時,在掃描完一個信道後,會立即跳到下一信道;但是對於Background Scan則不同,由於當前已經連接到某個AP,所以在切換掃描信道前,會返回已連接AP 的主信道停留一段時間,以便WiFi連接有一定的時間發送/接收數據,這個停留時間通常是幾十毫秒。