Вы можете использовать возможности сканирования Wi-Fi, предоставляемые API WifiManager , чтобы получить список точек доступа Wi-Fi, видимых с устройства.
процесс сканирования Wi-Fi
Процесс сканирования состоит из трех этапов:
Зарегистрируйте обработчик широковещательной рассылки для
SCAN_RESULTS_AVAILABLE_ACTION, который вызывается при завершении запросов на сканирование, предоставляя информацию об их успешности/неудаче. Для устройств под управлением Android 10 (уровень API 29) и выше эта рассылка будет отправляться при любом полном сканировании Wi-Fi, выполняемом на устройстве платформой или другими приложениями. Приложения могут пассивно отслеживать все завершения сканирования на устройстве, используя широковещательную рассылку, без запуска собственного сканирования.Запросите сканирование с помощью
WifiManager.startScan(). Обязательно проверьте возвращаемый метод, так как вызов может завершиться неудачей по одной из следующих причин:- Количество запросов на сканирование может быть ограничено из-за слишком большого числа сканирований за короткий промежуток времени.
- Устройство находится в режиме ожидания, сканирование отключено.
- Wi-Fi-оборудование сообщает о сбое сканирования.
Получите результаты сканирования с помощью
WifiManager.getScanResults(). Возвращаемые результаты сканирования являются самыми последними обновленными результатами, которые могут относиться к предыдущему сканированию, если текущее сканирование не завершилось или не прошло успешно. Это означает, что вы можете получить более старые результаты сканирования, если вызовете этот метод до получения успешного широковещательного сообщенияSCAN_RESULTS_AVAILABLE_ACTION.
Приведенный ниже код демонстрирует пример реализации этих шагов:
Котлин
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 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. - Службы определения местоположения включены на устройстве (в разделе «Настройки» > «Местоположение» ).
Для успешного вызова WifiManager.getScanResults() необходимо убедиться, что выполнены все следующие условия:
- Если ваше приложение ориентировано на Android 10 (уровень API 29) SDK или выше, оно имеет разрешение
ACCESS_FINE_LOCATION. - Если ваше приложение ориентировано на SDK ниже Android 10 (уровень API 29), оно имеет разрешение
ACCESS_COARSE_LOCATIONилиACCESS_FINE_LOCATION. - Ваше приложение имеет разрешение
ACCESS_WIFI_STATE. - Службы определения местоположения включены на устройстве (в разделе «Настройки» > «Местоположение» ).
Если вызывающее приложение не соответствует всем этим требованиям, вызов завершится с ошибкой SecurityException .
Регулирование скорости
К частоте сканирования с помощью WifiManager.startScan() применяются следующие ограничения.
Android 8.0 и Android 8.1:
Каждое фоновое приложение может выполнить сканирование один раз в течение 30 минут.
Android 9:
Каждое приложение, работающее в фоновом режиме, может выполнить четыре сканирования за 2 минуты. Это позволяет осуществить серию сканирований за короткий промежуток времени.
Все фоновые приложения вместе взятые могут выполнить сканирование один раз за 30 минут.
Android 10 и выше:
Действуют те же ограничения скорости, что и в Android 9. Появилась новая опция для разработчиков, позволяющая отключить ограничение скорости для локального тестирования (в разделе «Параметры разработчика» > «Сеть» > «Ограничение скорости сканирования Wi-Fi» ).