WifiManager API가 제공하는 Wi-Fi 검색 기능을 사용하여 기기에 보이는 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 ... }
자바
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)는 Wi-Fi 검색의 권한 요구 사항을 엄격하게 변경하고 그 빈도를 더욱 제한했습니다.
권한
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
권한이 있어야 합니다. - 앱이 Android 10(API 수준 29) 미만의 SDK를 타겟팅하는 경우
ACCESS_COARSE_LOCATION
또는ACCESS_FINE_LOCATION
권한이 필요합니다. - 앱에
CHANGE_WIFI_STATE
권한이 있어야 합니다. - 기기에서 위치 서비스가 활성화되어야 합니다(설정 > 위치 아래).
WifiManager.getScanResults()
를 호출하려면 다음 조건을 모두 충족해야 합니다.
- 앱이 Android 10(API 수준 29) SDK 이상을 타겟팅할 경우
ACCESS_FINE_LOCATION
권한이 있어야 합니다. - 앱이 Android 10(API 수준 29) 미만인 SDK를 타겟팅할 경우
ACCESS_COARSE_LOCATION
또는ACCESS_FINE_LOCATION
권한이 있어야 합니다. - 앱에
ACCESS_WIFI_STATE
권한이 있어야 합니다. - 기기에서 위치 서비스가 활성화되어야 합니다(설정 > 위치 아래).
호출하는 앱이 이러한 조건을 모두 충족하지 못하면 SecurityException
과 함께 호출이 실패합니다.
사용 제한
WifiManager.startScan()
을 사용하는 스캔 빈도에 다음과 같은 제한이 적용됩니다.
Android 8.0 및 Android 8.1:
각 백그라운드 앱은 30분 간격으로 1회 스캔할 수 있습니다.
Android 9:
각 포그라운드 앱은 2분 간격으로 4회 스캔할 수 있습니다. 이 경우, 단시간에 여러 번의 스캔이 가능하게 됩니다.
백그라운드 앱은 모두 합쳐서 30분 간격으로 1회 스캔할 수 있습니다.
Android 10 이상:
Android 9와 동일한 사용 제한이 적용됩니다. 로컬 테스트를 위해 사용 제한을 해제하는 새로운 개발자 옵션이 추가되었습니다(Developer Options > Networking > Wi-Fi scan throttling).