Kablosuz taramasına genel bakış

Cihazdan görülebilen kablosuz erişim noktalarının listesini almak için WifiManager API'nin sağladığı kablosuz ağ tarama özelliklerini kullanabilirsiniz.

Kablosuz ağ taraması işlemi

Tarama işlemi üç adımdan oluşur:

  1. SCAN_RESULTS_AVAILABLE_ACTION için bir yayın dinleyicisi kaydedin. Bu işlem, tarama istekleri tamamlandığında çağrılıp başarı/başarısızlık durumunu belirtir. Android 10 (API düzeyi 29) ve sonraki sürümleri çalıştıran cihazlarda bu yayın, platform veya diğer uygulamalar tarafından cihazda gerçekleştirilen tam kablosuz ağ taraması için gönderilir. Uygulamalar, kendi taramalarını yapmadan yayını kullanarak cihazdaki tüm tarama tamamlamalarını pasif olarak dinleyebilir.

  2. WifiManager.startScan() aracını kullanarak tarama isteğinde bulunun. Çağrı, aşağıdaki nedenlerden herhangi birinden dolayı başarısız olabileceğinden yöntemin döndürme durumunu kontrol ettiğinizden emin olun:

    • Kısa süre içinde çok fazla tarama yapıldığından tarama istekleri kısıtlanabilir.
    • Cihaz boşta ve tarama devre dışı bırakıldı.
    • Kablosuz donanımı bir tarama hatası bildirir.
  3. WifiManager.getScanResults() kullanarak tarama sonuçlarını alın. Döndürülen tarama sonuçları, en son güncellenmiş sonuçlardır. Mevcut taramanız henüz tamamlanmadıysa veya başarılı olmadıysa bu sonuçlar önceki taramadan alınmış olabilir. Diğer bir deyişle, başarılı bir SCAN_RESULTS_AVAILABLE_ACTION yayını almadan önce bu yöntemi çağırırsanız eski tarama sonuçları alabilirsiniz.

Aşağıdaki kod, bu adımların nasıl uygulanacağına dair bir örnek sunar:

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

Kısıtlamalar

Android 8.0 (API düzeyi 26), izinlerle ve kablosuz ağ taramalarının izin verilen sıklığıyla ilgili kısıtlamalar getirmekteydi.

Android 9 (API düzeyi 28) ağ performansını, güvenliği ve pil ömrünü iyileştirmek için izin gereksinimlerini sıkılaştırdı ve kablosuz ağ taramalarının sıklığını daha da sınırlandırdı.

İzinler

Android 8.0 ve Android 8.1:

WifiManager.getScanResults() çağrısının başarılı olması için aşağıdaki izinlerden herhangi biri gerekir:

Çağrı uygulaması bu izinlerden hiçbirine sahip değilse çağrı bir SecurityException ile başarısız olur.

Alternatif olarak, Android 8.0 (API düzeyi 26) ve sonraki sürümleri çalıştıran cihazlarda konum izni gerekmeksizin uygulamanız adına yakındaki tamamlayıcı cihazları taramak için CompanionDeviceManager kullanabilirsiniz. Bu seçenek hakkında daha fazla bilgi için Tamamlayıcı cihaz eşleme bölümünü inceleyin.

Android 9:

Başarılı bir WifiManager.startScan() çağrısı için aşağıdaki koşulların tümünün karşılanması gerekir:

Android 10 (API düzeyi 29) ve sonraki sürümler:

Başarılı bir WifiManager.startScan() çağrısı için aşağıdaki koşulların tümünün karşılanması gerekir:

WifiManager.getScanResults() çağrısını başarılı bir şekilde yapmak için aşağıdaki tüm koşulların sağlandığından emin olun:

  • Uygulamanız Android 10 (API düzeyi 29) SDK veya sonraki sürümleri hedefliyorsa ACCESS_FINE_LOCATION izni vardır.
  • Uygulamanız, Android 10'dan (API düzeyi 29) önceki SDK'ları hedefliyorsa ACCESS_COARSE_LOCATION veya ACCESS_FINE_LOCATION iznine sahip olur.
  • Uygulamanız ACCESS_WIFI_STATE iznine sahip.
  • Konum hizmetleri cihazda etkinleştirilir (Ayarlar > Konum altında).

Çağrı uygulaması bu gereksinimlerin tümünü karşılamıyorsa çağrı bir SecurityException ile başarısız olur.

Kısıtlama

WifiManager.startScan() kullanılarak yapılan taramaların sıklığı için aşağıdaki sınırlamalar geçerlidir.

Android 8.0 ve Android 8.1:

Arka plandaki her uygulama, 30 dakikalık süre içinde bir kez tarama yapabilir.

Android 9:

Her ön plan uygulaması, 2 dakikalık süre içinde dört kez tarama yapabilir. Bu da taramaların kısa sürede patlamasına olanak tanıyor.

Tüm arka plan uygulamaları birlikte 30 dakikalık süre içinde bir kez tarama yapabilir.

Android 10 ve sonraki sürümler:

Android 9'daki aynı kısıtlama sınırları geçerlidir. Yerel test kısıtlamayı kapatmak için geliştirici tarafından sunulan yeni bir seçenek mevcut (Geliştirici Seçenekleri > Ağ iletişimi > Kablosuz ağ taramasını kısıtlama altında).