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(API 수준 26) 및 Android 8.1(API 수준 27):
WifiManager.getScanResults()를 성공적으로 호출하려면 다음 권한 중 하나가 필요합니다.
호출하는 앱에 위의 권한 중 하나가 없을 경우, 호출은
SecurityException과 함께 실패합니다.
또는 Android 8.0(API 수준 26) 이상을 실행하는 기기에서 CompanionDeviceManager를 사용하여 위치 정보 액세스 권한 없이 앱을 대신해 근처 컴패니언 기기를 검색할 수 있습니다. 이 옵션에 관한 자세한 내용은 컴패니언 기기 페어링을 참고하세요.
Android 9(API 수준 28):
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와 동일한 사용 제한이 적용됩니다. 로컬 테스트를 위해 제한을 사용 중지하는 새로운 개발자 옵션이 있습니다(개발자 옵션 > 네트워킹 > Wi-Fi 검색 제한).