Możesz użyć funkcji skanowania Wi-Fi udostępnianych przez interfejs WifiManager API, aby uzyskać listę punktów dostępu Wi-Fi widocznych z urządzenia.
Proces skanowania Wi-Fi
Proces skanowania składa się z 3 etapów:
Zarejestruj odbiorcę transmisji dla
SCAN_RESULTS_AVAILABLE_ACTION, który jest wysyłany po zakończeniu żądań skanowania i podaje 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 Wi-Fi przeprowadzonego na urządzeniu przez platformę lub inne aplikacje. Aplikacje mogą pasywnie nasłuchiwać wszystkich skanowań na urządzeniu, korzystając z transmisji, bez konieczności przeprowadzania własnego skanowania.Poproś o skanowanie za pomocą
WifiManager.startScan(). Sprawdź stan zwracany przez metodę, ponieważ wywołanie może się nie powieść z tych powodów:- Żądania skanowania mogą być ograniczane z powodu zbyt wielu skanowań w krótkim czasie.
- Urządzenie jest nieaktywne, a skanowanie jest wyłączone.
- Sprzęt Wi-Fi zgłasza błąd skanowania.
Uzyskaj wyniki skanowania za pomocą
WifiManager.getScanResults(). Zwracane wyniki skanowania są ostatnio zaktualizowanymi wynikami, które mogą pochodzić z poprzedniego skanowania, jeśli bieżące skanowanie nie zostało ukończone lub się nie powiodło. Oznacza to, że jeśli wywołasz tę metodę przed otrzymaniem udanej transmisjiSCAN_RESULTS_AVAILABLE_ACTION, możesz uzyskać starsze wyniki skanowania.
Poniższy kod pokazuje, jak wykonać te czynności:
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 interfejsu API 28) zaostrzono wymagania dotyczące uprawnień i jeszcze bardziej ograniczono częstotliwość skanowania sieci Wi-Fi.
Uprawnienia
Android 8.0 (poziom API 26) i Android 8.1 (poziom API 27):
Udane wywołanie metody WifiManager.getScanResults() wymaga dowolnego z tych uprawnień:
Jeśli aplikacja do dzwonienia nie ma żadnego z tych uprawnień, połączenie nie powiedzie się i zostanie wyświetlony błąd SecurityException.
Możesz też użyć CompanionDeviceManager na urządzeniach z Androidem 8.0 (poziom interfejsu API 26) lub nowszym, aby przeskanować urządzenia towarzyszące w pobliżu w imieniu aplikacji bez konieczności uzyskiwania dostępu do lokalizacji. Więcej informacji o tej opcji znajdziesz w artykule Parowanie urządzeń towarzyszących.
Android 9 (poziom 28 interfejsu API):
Aby wywołanie WifiManager.startScan() zakończyło się powodzeniem, muszą być spełnione wszystkie te warunki:
- Twoja aplikacja ma uprawnienie
ACCESS_FINE_LOCATIONlubACCESS_COARSE_LOCATION. - Twoja aplikacja ma uprawnienie
CHANGE_WIFI_STATE. - Na urządzeniu są włączone usługi lokalizacyjne (w sekcji Ustawienia > Lokalizacja).
Android 10 (poziom interfejsu API 29) i nowsze wersje:
Aby wywołanie WifiManager.startScan() zakończyło się powodzeniem, muszą być spełnione wszystkie te warunki:
- Jeśli Twoja aplikacja jest kierowana na pakiet SDK Androida 10 (API na poziomie 29) lub nowszego, ma uprawnienie
ACCESS_FINE_LOCATION. - Jeśli Twoja aplikacja jest kierowana na pakiet SDK niższy niż Android 10 (poziom API 29), ma uprawnienie
ACCESS_COARSE_LOCATIONlubACCESS_FINE_LOCATION. - Twoja aplikacja ma uprawnienie
CHANGE_WIFI_STATE. - Na urządzeniu są włączone usługi lokalizacyjne (w sekcji Ustawienia > Lokalizacja).
Aby pomyślnie wywołać WifiManager.getScanResults(), upewnij się, że spełnione są wszystkie te warunki:
- Jeśli Twoja aplikacja jest kierowana na pakiet SDK Androida 10 (API na poziomie 29) lub nowszego, ma uprawnienie
ACCESS_FINE_LOCATION. - Jeśli Twoja aplikacja jest kierowana na pakiet SDK niższy niż Android 10 (poziom API 29), ma uprawnienie
ACCESS_COARSE_LOCATIONlubACCESS_FINE_LOCATION. - Twoja aplikacja ma uprawnienie
ACCESS_WIFI_STATE. - Na urządzeniu są włączone usługi lokalizacyjne (w sekcji Ustawienia > Lokalizacja).
Jeśli aplikacja do dzwonienia nie spełnia wszystkich tych wymagań, połączenie nie powiedzie się i zostanie wyświetlony błąd SecurityException.
Ograniczanie
W przypadku częstotliwości skanowania za pomocą WifiManager.startScan() obowiązują te ograniczenia:
Android 8.0 i Android 8.1:
Każda aplikacja działająca w tle może skanować raz na 30 minut.
Android 9:
Każda aplikacja na pierwszym planie może skanować 4 razy w ciągu 2 minut. Umożliwia to wykonanie wielu skanów w krótkim czasie.
Wszystkie aplikacje działające w tle mogą przeprowadzić 1 skanowanie w ciągu 30 minut.
Android 10 lub nowszy:
Obowiązują te same limity ograniczania przepustowości co w Androidzie 9. Dostępna jest nowa opcja dla deweloperów, która pozwala wyłączyć ograniczanie na potrzeby testów lokalnych (Opcje programisty > Sieć > Ograniczanie skanowania Wi-Fi).