Możesz użyć funkcji skanowania sieci Wi-Fi udostępnianych przez interfejs WifiManager API, aby uzyskać listę punktów dostępu Wi-Fi widocznych na urządzeniu.
Proces skanowania Wi-Fi
Proces skanowania składa się z 3 etapów:
Zarejestruj odbiornik transmisji dla
SCAN_RESULTS_AVAILABLE_ACTION
, który jest wywoływany po zakończeniu żądań skanowania i zwraca stan powodzenia lub niepowodzenia. W przypadku urządzeń z Androidem 10 (poziom interfejsu API 29) lub nowszym ta transmisja będzie wysyłana w przypadku każdego pełnego skanowania sieci Wi-Fi przeprowadzonego na urządzeniu przez platformę lub inne aplikacje. Aplikacje mogą pasywnie słuchać wszystkich zakończeń skanowania na urządzeniu, korzystając z transmisji bez przeprowadzania własnego skanowania.Poproś o skanowanie, korzystając z
WifiManager.startScan()
. Sprawdź stan zwracania metody, ponieważ wywołanie może się nie udać z jednego z tych powodów:- Żądania skanowania mogą być ograniczane ze względu na zbyt dużą liczbę skanowań w krótkim czasie.
- Urządzenie jest nieaktywne, a skanowanie jest wyłączone.
- Sprzęt Wi-Fi zgłasza błąd skanowania.
Pobierz wyniki skanowania, używając
WifiManager.getScanResults()
. Zwrócone wyniki skanowania to najnowsze zaktualizowane wyniki, które mogą pochodzić z poprzedniego skanowania, jeśli bieżące skanowanie nie zostało ukończone lub nie powiodło się. Oznacza to, że jeśli wywołasz tę metodę przed otrzymaniem udanej transmisjiSCAN_RESULTS_AVAILABLE_ACTION
, możesz otrzymać starsze wyniki skanowania.
Poniżej znajdziesz kod, który pokazuje, jak zastosować te kroki:
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 ... }
Ograniczenia
W Androidzie 8.0 (poziom interfejsu API 26) wprowadzono ograniczenia dotyczące uprawnień i dozwolonej częstotliwości skanowania sieci Wi-Fi.
Aby poprawić wydajność sieci, bezpieczeństwo i czas pracy na baterii, w Androidzie 9 (poziom API 28) zaostrzyliśmy wymagania dotyczące uprawnień i jeszcze bardziej ograniczyliśmy częstotliwość skanowania sieci Wi-Fi.
Uprawnienia
Android 8.0 i 8.1:
Aby wywołać szablon WifiManager.getScanResults()
, musisz mieć co najmniej jedno z tych uprawnień:
Jeśli aplikacja do wykonywania połączeń nie ma żadnego z tych uprawnień, połączenie nie powiedzie się i zostanie wyświetlony komunikat SecurityException
.
Na urządzeniach z Androidem 8.0 (poziom interfejsu API 26) lub nowszym możesz też użyć CompanionDeviceManager
, aby skanować urządzenia towarzyszące w pobliżu w imieniu aplikacji bez konieczności uzyskiwania uprawnień do lokalizacji. Więcej informacji o tej opcji znajdziesz w artykule Parowanie urządzenia towarzyszącego.
Android 9:
Aby wywołanie funkcji WifiManager.startScan()
zakończyło się powodzeniem, muszą być spełnione wszystkie te warunki:
- Twoja aplikacja ma uprawnienie
ACCESS_FINE_LOCATION
lubACCESS_COARSE_LOCATION
. - Twoja aplikacja ma uprawnienie
CHANGE_WIFI_STATE
. - Usługi lokalizacyjne są włączone na urządzeniu (w sekcji Ustawienia > Lokalizacja).
Android 10 (poziom 29 interfejsu API) i nowsze:
Aby wywołanie funkcji WifiManager.startScan()
zakończyło się powodzeniem, muszą być spełnione wszystkie te warunki:
- Jeśli Twoja aplikacja jest kierowana na Androida 10 (API na poziomie 29) lub nowszego, ma ona uprawnienie
ACCESS_FINE_LOCATION
. - Jeśli Twoja aplikacja jest kierowana na SDK niższego niż Android 10 (poziom interfejsu API 29), ma ona uprawnienia
ACCESS_COARSE_LOCATION
lubACCESS_FINE_LOCATION
. - Twoja aplikacja ma uprawnienie
CHANGE_WIFI_STATE
. - Usługi lokalizacyjne są włączone na urządzeniu (w sekcji Ustawienia > Lokalizacja).
Aby wywołać funkcję WifiManager.getScanResults()
, musisz spełnić wszystkie te warunki:
- Jeśli Twoja aplikacja jest kierowana na pakiet Androida 10 (API na poziomie 29) lub nowszy, ma uprawnienie
ACCESS_FINE_LOCATION
. - Jeśli Twoja aplikacja jest kierowana na SDK niższego niż Android 10 (poziom interfejsu API 29), ma ona uprawnienia
ACCESS_COARSE_LOCATION
lubACCESS_FINE_LOCATION
. - Twoja aplikacja ma uprawnienie
ACCESS_WIFI_STATE
. - Usługi lokalizacyjne są włączone na urządzeniu (w sekcji Ustawienia > Lokalizacja).
Jeśli aplikacja do wykonywania połączeń nie spełnia wszystkich tych wymagań, połączenie nie zostanie nawiązane i usłyszysz komunikat SecurityException
.
Ograniczanie
Częstotliwość skanowania za pomocą WifiManager.startScan()
jest ograniczona do tych wartości.
Android 8.0 i 8.1:
Każda aplikacja działająca w tle może skanować raz w ciągu 30 minut.
Android 9:
Każda aplikacja na pierwszym planie może skanować cztery razy w ciągu 2 minut. Umożliwia to skanowanie dużej liczby plików w krótkim czasie.
Wszystkie aplikacje działające w tle mogą skanować raz w ciągu 30 minut.
Android 10 lub nowszy:
Obowiązują te same limity ograniczania, co w Androidzie 9. Dodano nową opcję dla programistów, która umożliwia wyłączenie ograniczania przepustowości w celu przeprowadzenia testów lokalnych (w sekcji Opcje programisty > Sieć > Ograniczanie przepustowości skanowania Wi-Fi).