Ringkasan pemindaian Wi-Fi

Anda dapat menggunakan kapabilitas pemindaian Wi-Fi yang disediakan oleh WifiManager API untuk mendapatkan daftar titik akses Wi-Fi yang terlihat dari perangkat.

Proses pemindaian Wi-Fi

Ada tiga langkah untuk proses pemindaian:

  1. Daftarkan pemroses siaran untuk SCAN_RESULTS_AVAILABLE_ACTION, yang dipanggil saat permintaan pemindaian selesai, dengan memberikan status keberhasilan/kegagalannya. Untuk perangkat yang menjalankan Android (API level 29) dan yang lebih tinggi, siaran ini akan dikirim untuk pemindaian Wi-Fi penuh yang dilakukan pada perangkat oleh platform atau aplikasi lain. Aplikasi dapat secara pasif mendengarkan semua pemindaian pada perangkat menggunakan siaran tanpa mengeluarkan pemindaiannya sendiri.

  2. Minta pemindaian menggunakan WifiManager.startScan(). Pastikan untuk memeriksa status pengembalian metode ini, karena panggilan bisa saja gagal karena salah satu penyebab berikut:

    • Permintaan pemindaian mungkin diperketat karena terlalu banyak pemindaian dalam waktu singkat.
    • Perangkat menganggur dan pemindaian dinonaktifkan.
    • Perangkat keras Wi-Fi melaporkan kegagalan pemindaian.
  3. Dapatkan hasil pemindaian menggunakan WifiManager.getScanResults(). Hasil pemindaian yang dikembalikan adalah hasil pembaruan terkini, yang mungkin berasal dari pemindaian sebelumnya jika pemindaian Anda saat ini belum selesai atau berhasil. Ini berarti Anda mungkin mendapatkan hasil pemindaian yang lebih lama jika Anda memanggil metode ini sebelum menerima siaran SCAN_RESULTS_AVAILABLE_ACTION yang berhasil.

Kode berikut memberikan contoh cara menerapkan langkah-langkah ini:

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

Batasan

Android 8.0 (API level 26) memperkenalkan batasan terkait izin dan frekuensi pemindaian Wi-Fi yang diizinkan.

Untuk menyempurnakan performa jaringan, keamanan, dan masa pakai baterai, Android 9 (level 28) memperketat persyaratan izin dan makin membatasi frekuensi pemindaian Wi-Fi.

Izin

Android 8.0 dan Android 8.1:

Panggilan WifiManager.getScanResults() yang berhasil memerlukan salah satu izin berikut:

Jika aplikasi panggilan tidak memiliki izin ini, panggilan gagal dengan SecurityException.

Atau, pada perangkat yang menjalankan Android 8.0 (API level 26) dan yang lebih tinggi, Anda dapat menggunakan CompanionDeviceManager untuk melakukan pemindaian perangkat pendamping di sekitar atas nama aplikasi Anda tanpa memerlukan izin lokasi. Untuk informasi tentang opsi ini selengkapnya, lihat Penyandingan perangkat pendamping.

Android 9:

Panggilan WifiManager.startScan() yang berhasil harus memenuhi semua ketentuan berikut:

Android 10 (API level 29) dan yang lebih tinggi.

Panggilan WifiManager.startScan() yang berhasil harus memenuhi semua ketentuan berikut:

  • Jika aplikasi Anda menargetkan SDK Android 10 (API level 29) atau yang lebih tinggi, aplikasi Anda memiliki izin ACCESS_FINE_LOCATION.
  • Jika aplikasi Anda menargetkan SDK lebih rendah dari Android 10 (API level 29), aplikasi Anda memiliki izin ACCESS_COARSE_LOCATION atau ACCESS_FINE_LOCATION.
  • Aplikasi Anda memiliki izin CHANGE_WIFI_STATE.
  • Layanan lokasi diaktifkan pada perangkat (dalam Setelan > Lokasi).

Agar pemanggilan WifiManager.getScanResults() berhasil, pastikan semua ketentuan berikut ini terpenuhi:

  • Jika aplikasi Anda menargetkan SDK Android 10 (API level 29) atau yang lebih tinggi, aplikasi Anda memiliki izin ACCESS_FINE_LOCATION.
  • Jika aplikasi Anda menargetkan SDK lebih rendah dari Android 10 (API level 29), aplikasi Anda memiliki izin ACCESS_COARSE_LOCATION atau ACCESS_FINE_LOCATION.
  • Aplikasi Anda memiliki izin ACCESS_WIFI_STATE.
  • Layanan lokasi diaktifkan pada perangkat (dalam Setelan > Lokasi).

Jika aplikasi panggilan tidak memenuhi semua persyaratan ini, panggilan gagal dengan SecurityException.

Throttling

Batasan berikut berlaku untuk frekuensi pemindaian menggunakan WifiManager.startScan().

Android 8.0 dan Android 8.1:

Setiap aplikasi latar belakang dapat memindai satu kali dalam periode 30 menit.

Android 9:

Setiap aplikasi latar depan dapat memindai empat kali dalam periode 2 menit. Ini memungkinkan pemindaian dalam waktu singkat.

Semua aplikasi latar belakang yang digabungkan dapat memindai satu kali dalam periode 30 menit.

Android 10 dan yang lebih tinggi:

Berlaku batas throttling yang sama dari Android 9. Ada opsi developer baru untuk mengaktifkan throttling untuk pengujian lokal (dalam Opsi Developer > Jaringan > Throttling pemindaian Wi-Fi).