이제 Android 11 개발자 프리뷰를 사용할 수 있습니다. 테스트해 보고 의견을 공유하세요.

Wi-Fi 검색 개요

WifiManager API가 제공하는 Wi-Fi 검색 기능을 사용하여 기기에 보이는 Wi-Fi 액세스 포인트의 목록을 가져올 수 있습니다.

Wi-Fi 검색 프로세스

스캔 프로세스는 세 가지 단계로 구성됩니다.

  1. SCAN_RESULTS_AVAILABLE_ACTION에 대한 Broadcast Receiver를 등록합니다. 이 수신기는 스캔 요청이 완료된 후에 호출되어 성공/실패 상태를 제공합니다. Android 10 (API 레벨 29) 이상를 실행하는 기기의 경우, 이 브로드캐스트는 플랫폼이나 다른 앱이 기기에 대해 수행하는 모든 전체 Wi-Fi 검색에 전송됩니다. 앱은 직접 스캔하지 않고도 이 브로드캐스트를 사용하여 기기에 대한 모든 스캔 완료 상태를 수동적으로 수신할 수 있습니다.

  2. WifiManager.startScan()을 사용하여 스캔을 요청하세요. 다음과 같은 이유에 해당하면 호출이 실패할 수 있으므로 메서드의 반환 상태를 확인하세요.

    • 단시간에 지나치게 많은 스캔으로 인해 스캔 요청이 제한될 수 있습니다.
    • 기기는 유휴 상태가 되고 스캔은 비활성화됩니다.
    • Wi-Fi 하드웨어가 스캔 실패를 보고합니다.
  3. 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)는 Wi-Fi 검색의 권한 요구 사항을 엄격하게 변경하고 그 빈도를 더욱 제한했습니다.

권한

Android 8.0 및 Android 8.1:

WifiManager.getScanResults()를 성공적으로 호출하려면 다음 권한 중 하나가 필요합니다.

호출하는 앱에 위의 권한 중 하나가 없을 경우, 호출은 SecurityException과 함께 실패합니다.

Android 9:

WifiManager.startScan()을 성공적으로 호출하려면 다음의 모든 조건이 충족되어야 합니다.

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 권한이 있어야 합니다.
  • 기기에서 위치 서비스가 활성화되어야 합니다(Settings > Location).

WifiManager.getScanResults()를 성공적으로 호출하려면 다음의 모든 조건이 충족되어야 합니다.

  • 앱이 Android 10 (API 레벨 29) SDK 이상을 대상으로 할 경우, 앱에 ACCESS_FINE_LOCATION 권한이 있어야 합니다.
  • 앱이 Android 10 (API 레벨 29) 이하의 SDK를 대상으로 할 경우, 앱에 ACCESS_COARSE_LOCATION 또는 ACCESS_FINE_LOCATION 권한이 있어야 합니다.
  • 앱에 ACCESS_WIFI_STATE 권한이 있어야 합니다.
  • 기기에서 위치 서비스가 활성화되어야 합니다(Settings > Location).

WifiManager.getScanResults()를 성공적으로 호출하려면 다음의 모든 조건이 충족되어야 합니다.

호출하는 앱이 위의 모든 요구 사항을 충족하지 않을 경우, 호출이 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).