WLAN-Suche – Übersicht

Mit den WLAN-Scanfunktionen der WifiManager API kannst du eine Liste der WLAN-Zugangspunkte abrufen, die vom Gerät aus sichtbar sind.

WLAN-Suche

Der Scanvorgang umfasst drei Schritte:

  1. Registrieren Sie einen Broadcast-Listener für SCAN_RESULTS_AVAILABLE_ACTION, der gesendet wird, wenn Scananfragen abgeschlossen sind, und der den Status „Erfolgreich“ oder „Fehlgeschlagen“ angibt. Auf Geräten mit Android 10 (API-Level 29) und höher wird dieser Broadcast für jeden vollständigen WLAN-Scan gesendet, der von der Plattform oder anderen Apps auf dem Gerät durchgeführt wird. Apps können alle abgeschlossenen Scans auf dem Gerät passiv abhören, indem sie den Broadcast verwenden, ohne selbst einen Scan auszuführen.

  2. Fordern Sie einen Scan an, indem Sie WifiManager.startScan() verwenden. Prüfen Sie den Rückgabestatus der Methode, da der Aufruf aus einem der folgenden Gründe fehlschlagen kann:

    • Scan-Anfragen können aufgrund zu vieler Scans in kurzer Zeit gedrosselt werden.
    • Das Gerät ist inaktiv und das Scannen ist deaktiviert.
    • Die WLAN-Hardware meldet einen Scanfehler.
  3. Scanergebnisse mit WifiManager.getScanResults() abrufen. Die zurückgegebenen Scanergebnisse sind die zuletzt aktualisierten Ergebnisse. Diese können von einem vorherigen Scan stammen, wenn der aktuelle Scan noch nicht abgeschlossen oder erfolgreich war. Das bedeutet, dass Sie möglicherweise ältere Scanergebnisse erhalten, wenn Sie diese Methode aufrufen, bevor Sie einen erfolgreichen SCAN_RESULTS_AVAILABLE_ACTION-Broadcast erhalten.

Der folgende Code enthält ein Beispiel für die Implementierung dieser Schritte:

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 ...
}

Einschränkungen

Mit Android 8.0 (API-Level 26) wurden Einschränkungen hinsichtlich der Berechtigungen und der zulässigen Häufigkeit von WLAN-Scans eingeführt.

Um die Netzwerkleistung, die Sicherheit und die Akkulaufzeit zu verbessern, wurden in Android 9 (API-Level 28) die Berechtigungsanforderungen verschärft und die Häufigkeit von WLAN-Scans weiter eingeschränkt.

Berechtigungen

Android 8.0 (API-Level 26) und Android 8.1 (API-Level 27):

Für einen erfolgreichen Aufruf von WifiManager.getScanResults() ist eine der folgenden Berechtigungen erforderlich:

Wenn die Anruf-App keine dieser Berechtigungen hat, schlägt der Aufruf mit einem SecurityException fehl.

Alternativ können Sie auf Geräten mit Android 8.0 (API-Level 26) und höher den CompanionDeviceManager verwenden, um im Namen Ihrer App nach Companion-Geräten in der Nähe zu suchen, ohne die Berechtigung zur Standortermittlung zu benötigen. Weitere Informationen zu dieser Option findest du unter Kopplung von Companion-Geräten.

Android 9 (API-Level 28):

Für einen erfolgreichen Aufruf von WifiManager.startScan() müssen alle der folgenden Bedingungen erfüllt sein:

  • Ihre App hat die Berechtigung ACCESS_FINE_LOCATION oder ACCESS_COARSE_LOCATION.
  • Ihre App hat die Berechtigung „CHANGE_WIFI_STATE“.
  • Die Standortdienste sind auf dem Gerät aktiviert (unter Einstellungen > Standort).

Android 10 (API-Level 29) und höher:

Für einen erfolgreichen Aufruf von WifiManager.startScan() müssen alle der folgenden Bedingungen erfüllt sein:

  • Wenn Ihre App auf das Android 10 SDK (API-Level 29) oder höher ausgerichtet ist, hat sie die Berechtigung ACCESS_FINE_LOCATION.
  • Wenn Ihre App auf ein SDK ausgerichtet ist, das niedriger als Android 10 (API-Level 29) ist, hat sie die Berechtigung ACCESS_COARSE_LOCATION oder ACCESS_FINE_LOCATION.
  • Ihre App hat die Berechtigung „CHANGE_WIFI_STATE“.
  • Die Standortdienste sind auf dem Gerät aktiviert (unter Einstellungen > Standort).

Damit WifiManager.getScanResults() erfolgreich aufgerufen werden kann, müssen alle der folgenden Bedingungen erfüllt sein:

  • Wenn Ihre App auf das Android 10 SDK (API-Level 29) oder höher ausgerichtet ist, hat sie die Berechtigung ACCESS_FINE_LOCATION.
  • Wenn Ihre App auf ein SDK ausgerichtet ist, das niedriger als Android 10 (API-Level 29) ist, hat sie die Berechtigung ACCESS_COARSE_LOCATION oder ACCESS_FINE_LOCATION.
  • Ihre App hat die Berechtigung ACCESS_WIFI_STATE.
  • Die Standortdienste sind auf dem Gerät aktiviert (unter Einstellungen > Standort).

Wenn die aufrufende App nicht alle diese Anforderungen erfüllt, schlägt der Aufruf mit SecurityException fehl.

Drosselung

Für die Häufigkeit von Scans mit WifiManager.startScan() gelten die folgenden Einschränkungen.

Android 8.0 und Android 8.1:

Jede Hintergrund-App kann innerhalb von 30 Minuten einmal scannen.

Android 9:

Jede App im Vordergrund kann innerhalb von zwei Minuten viermal scannen. Dies ermöglicht eine Reihe von Scans in kurzer Zeit.

Alle Hintergrund-Apps zusammen können innerhalb von 30 Minuten einmal scannen.

Android 10 und höher:

Es gelten dieselben Drosselungslimits wie bei Android 9. Es gibt eine neue Entwickleroption, mit der die Drosselung für lokale Tests deaktiviert werden kann (unter Entwickleroptionen > Netzwerk > Drosselung der WLAN-Suche).