您可以使用 WifiManager API 取得 可透過裝置顯示的 Wi-Fi 存取點。
Wi-Fi 掃描程序
掃描程序包含三個步驟:
註冊廣播事件監聽器:
SCAN_RESULTS_AVAILABLE_ACTION
、 當系統完成掃描請求時,系統就會呼叫此方法 。如果是搭載 Android 10 (API 級別 29) 以上版本的裝置,這個 將會在裝置完整掃描 Wi-Fi 時,將 平台或其他應用程式應用程式可以被動聆聽所有掃描 透過廣播確保裝置完整播放使用以下電子郵件地址要求掃描:
WifiManager.startScan()
。 呼叫可能會失敗,請務必檢查方法的傳回狀態 :- 由於短時間內掃描的掃描過多,掃描要求可能會受到限制。
- 裝置處於閒置狀態,因此掃描功能已停用。
- Wi-Fi 硬體回報掃描失敗。
取得掃描結果:
WifiManager.getScanResults()
。 傳回的掃描結果是最近更新的結果, 如果您目前的掃描作業尚未完成或成功,則執行先前的掃描作業 這代表如果呼叫這個方法,可能會傳回較舊的掃描結果 才會收到成功SCAN_RESULTS_AVAILABLE_ACTION
敬上 廣播。
以下程式碼範例說明如何實作這些步驟:
Kotlin
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager val wifiScanReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false) if (success) { scanSuccess() } else { scanFailure() } } } val intentFilter = IntentFilter() intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) context.registerReceiver(wifiScanReceiver, intentFilter) val success = wifiManager.startScan() if (!success) { // scan failure handling scanFailure() } .... private fun scanSuccess() { val results = wifiManager.scanResults ... use new scan results ... } private fun scanFailure() { // handle failure: new scan did NOT succeed // consider using old scan results: these are the OLD results! val results = wifiManager.scanResults ... potentially use older scan results ... }
Java
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() { @Override public void onReceive(Context c, Intent intent) { boolean success = intent.getBooleanExtra( WifiManager.EXTRA_RESULTS_UPDATED, false); if (success) { scanSuccess(); } else { // scan failure handling scanFailure(); } } }; IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); context.registerReceiver(wifiScanReceiver, intentFilter); boolean success = wifiManager.startScan(); if (!success) { // scan failure handling scanFailure(); } .... private void scanSuccess() { List<ScanResult> results = wifiManager.getScanResults(); ... use new scan results ... } private void scanFailure() { // handle failure: new scan did NOT succeed // consider using old scan results: these are the OLD results! List<ScanResult> results = wifiManager.getScanResults(); ... potentially use older scan results ... }
限制
Android 8.0 (API 級別 26) 推出了有關權限和 以及允許掃描 Wi-Fi 的頻率。
為了提升網路效能、安全性和電池續航力,Android 9 (API) 第 28 級) 限縮權限要求,並進一步限制 。
權限
Android 8.0 和 Android 8.1:
成功呼叫
WifiManager.getScanResults()
敬上
需要下列其中一項權限:
如果發出呼叫的應用程式並未擁有上述任何權限,呼叫就會失敗,並顯示
SecurityException
。
或者,在搭載 Android 8.0 (API 級別 26) 以上版本的裝置上,您也可以
請使用
CompanionDeviceManager
敬上
可以代表您的應用程式掃描鄰近的隨附裝置
要求位置存取權。如要進一步瞭解這個選項,請參閱
配對裝置
配對。
Android 9:
成功呼叫
WifiManager.startScan()
敬上
必須符合下列「所有」條件:
- 您的應用程式含有
ACCESS_FINE_LOCATION
敬上 或ACCESS_COARSE_LOCATION
權限。 - 您的應用程式含有
CHANGE_WIFI_STATE
敬上 權限。 - 裝置上已啟用定位服務 (在「設定」>「位置」下)。
Android 10 (API 級別 29) 以上版本:
成功呼叫
WifiManager.startScan()
敬上
必須符合下列「所有」條件:
- 如果您的應用程式指定 Android 10 (API 級別 29) SDK 以上版本,
具有
ACCESS_FINE_LOCATION
敬上 權限。 - 如果應用程式指定的 SDK 版本低於 Android 10 (API 級別 29),則應用程式
具有
ACCESS_COARSE_LOCATION
敬上 或ACCESS_FINE_LOCATION
權限。 - 您的應用程式含有
CHANGE_WIFI_STATE
權限。 - 裝置已啟用定位服務 (在「設定」之下 > Location)。
為了成功呼叫
WifiManager.getScanResults()
、
確保符合下列「所有」條件:
- 如果您的應用程式指定 Android 10 (API 級別 29) SDK 以上版本,
擁有
ACCESS_FINE_LOCATION
權限。 - 如果應用程式指定的 SDK 版本低於 Android 10 (API 級別 29),則應用程式
擁有
ACCESS_COARSE_LOCATION
或ACCESS_FINE_LOCATION
權限。 - 您的應用程式含有
ACCESS_WIFI_STATE
敬上 權限。 - 裝置已啟用定位服務 (在「設定」之下 > Location)。
如果發出呼叫的應用程式不符合上述所有規定,則呼叫會失敗,並顯示
SecurityException
。
節流
下列限制適用於使用
WifiManager.startScan()
。
Android 8.0 和 Android 8.1:
每個背景應用程式可在 30 分鐘內掃描一次。
Android 9:
每個前景應用程式可在 2 分鐘內掃描 4 次。這樣一來 迅速執行大量掃描
所有背景應用程式合併的單位可在 30 分鐘內掃描一次。
Android 10 以上版本:
也適用 Android 9 的節流限制。有新的開發人員選項 關閉本機測試的節流設定 (在「開發人員選項」> 網路 >Wi-Fi 掃描節流)。