Вы можете использовать возможности сканирования Wi-Fi, предоставляемые 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) были ужесточены требования к разрешениям и ограничена частота сканирования сетей 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. - Если целевая версия 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:
Каждое активное приложение может выполнять сканирование четыре раза за двухминутный период. Это позволяет выполнить серию сканирований за короткое время.
Все фоновые приложения вместе могут выполнять сканирование один раз в 30 минут.
Android 10 и более поздних версий:
Применяются те же ограничения, что и в Android 9. В разделе Для разработчиков > Сети > Ограничение сканирования Wi-Fi можно отключить ограничение для локального тестирования.