نمای کلی اسکن Wi-Fi

می‌توانید از قابلیت‌های اسکن Wi-Fi ارائه‌شده توسط WifiManager API برای دریافت فهرست نقاط دسترسی Wi-Fi که از دستگاه قابل‌مشاهده هستند استفاده کنید.

فرایند اسکن کردن Wi-Fi

فرایند اسکن کردن سه مرحله دارد:

  1. ثبت شنونده همه‌فرستی برای SCAN_RESULTS_AVAILABLE_ACTION، که وقتی درخواست‌های اسکن تکمیل می‌شود فراخوانی می‌شود و وضعیت موفقیت/شکست آن‌ها را ارائه می‌دهد. برای دستگاه‌هایی که Android 10 (سطح میانای برنامه‌سازی کاربردی ۲۹) و بالاتر را اجرا می‌کنند، این همه‌فرستی برای هر اسکن کامل Wi-Fi که توسط پلاتفرم یا برنامه‌های دیگر در دستگاه انجام شود ارسال خواهد شد. برنامه‌ها می‌توانند بااستفاده از همه‌فرستی، بدون اینکه خودشان اسکن انجام دهند، به‌طور غیرفعال به همه اسکن‌های تکمیل‌شده در دستگاه گوش دهند.

  2. بااستفاده از WifiManager.startScan()، درخواست اسکن کنید. حتماً وضعیت برگرداندن روش را بررسی کنید، زیرا ممکن است تماس به‌دلیل هریک از موارد زیر ناموفق باشد:

    • ممکن است درخواست‌های اسکن به‌دلیل تعداد زیاد اسکن در مدت زمان کوتاه محدود شود.
    • دستگاه در حالت آزاد است و اسکن غیرفعال است.
    • سخت‌افزار Wi-Fi خطای اسکن گزارش می‌کند.
  3. دریافت نتایج اسکن بااستفاده از WifiManager.getScanResults(). نتایج اسکن برگردانده‌شده جدیدترین نتایج به‌روزشده هستند که ممکن است مربوط به اسکن قبلی باشند، اگر اسکن فعلی شما تکمیل یا موفقیت‌آمیز نبوده باشد. یعنی اگر این روش را قبل‌از دریافت همه‌فرستی موفق SCAN_RESULTS_AVAILABLE_ACTION فراخوانی کنید، ممکن است نتایج اسکن قدیمی‌تری دریافت کنید.

کد زیر نمونه‌ای از نحوه اجرای این مراحل را ارائه می‌دهد:

کاتلین

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

جاوا

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

محدودیت‌ها

Android 8.0 (سطح میانای برنامه‌سازی کاربردی ۲۶) محدودیت‌هایی را درخصوص اجازه‌ها و بسامد مجاز اسکن‌های Wi-Fi معرفی کرد.

برای بهبود عملکرد شبکه، امنیت، و عمر باتری، Android 9 (سطح API‏ ۲۸) الزامات اجازه را سخت‌تر کرده است و دفعات اسکن Wi-Fi را بیشتر محدود کرده است.

اجازه‌ها

Android 8.0 و Android 8.1:

فراخوانی موفق به WifiManager.getScanResults() به یکی از اجازه‌های زیر نیاز دارد:

اگر برنامه برقراری تماس هیچ‌کدام از این اجازه‌ها را نداشته باشد، تماس با SecurityException ناموفق می‌شود.

همچنین، در دستگاه‌هایی که Android نسخه ۸.۰ (سطح میانای برنامه‌سازی کاربردی ۲۶) و بالاتر دارند، می‌توانید از CompanionDeviceManager استفاده کنید تا دستگاه‌های همپا در اطراف را ازطرف برنامه‌تان اسکن کنید، بدون اینکه به اجازه مکان نیاز داشته باشید. برای اطلاعات بیشتر درباره این گزینه، جفت‌سازی دستگاه همپا را ببینید.

Android 9:

برای اینکه تماس با WifiManager.startScan() موفقیت‌آمیز باشد، باید همه شرایط زیر برآورده شود:

‫Android 10 (میانای برنامه‌سازی کاربردی سطح ۲۹) و بالاتر:

برای اینکه تماس با WifiManager.startScan() موفقیت‌آمیز باشد، باید همه شرایط زیر برآورده شود:

  • اگر برنامه شما کیت توسعه نرم‌افزار Android 10 (سطح میانای برنامه‌سازی کاربردی ۲۹) یا بالاتر را هدف قرار می‌دهد، برنامه شما اجازه ACCESS_FINE_LOCATION را دارد.
  • اگر برنامه شما کیت توسعه نرم‌افزار پایین‌تر از Android 10 (سطح میانای برنامه‌سازی کاربردی ۲۹) را هدف قرار می‌دهد، برنامه شما اجازه ACCESS_COARSE_LOCATION یا ACCESS_FINE_LOCATION را دارد.
  • برنامه شما اجازه CHANGE_WIFI_STATE را دارد.
  • خدمات مکان در دستگاه فعال باشد (در تنظیمات > مکان).

برای تماس موفقیت‌آمیز با WifiManager.getScanResults()، مطمئن شوید همه شرایط زیر برآورده شده باشد:

  • اگر برنامه شما کیت توسعه نرم‌افزار Android 10 (سطح میانای برنامه‌سازی کاربردی ۲۹) یا بالاتر را هدف قرار می‌دهد، برنامه شما اجازه ACCESS_FINE_LOCATION را دارد.
  • اگر برنامه شما کیت توسعه نرم‌افزار پایین‌تر از Android 10 (سطح میانای برنامه‌سازی کاربردی ۲۹) را هدف‌یابی می‌کند، برنامه شما اجازه ACCESS_COARSE_LOCATION یا ACCESS_FINE_LOCATION را دارد.
  • برنامه شما اجازه ACCESS_WIFI_STATE دارد.
  • خدمات مکان در دستگاه فعال باشد (در تنظیمات > مکان).

اگر برنامه برقراری تماس همه این الزامات را برآورده نکند، تماس با SecurityException ناموفق می‌شود.

محدود کردن

محدودیت‌های زیر بر بسامد اسکن‌ها بااستفاده از WifiManager.startScan() اعمال می‌شود.

Android 8.0 و Android 8.1:

هر برنامه پس‌زمینه می‌تواند یک‌بار در یک دوره ۳۰ دقیقه‌ای اسکن کند.

Android 9:

هر برنامه پیش‌زمینه می‌تواند چهار بار در یک دوره ۲ دقیقه‌ای اسکن کند. این کار امکان اسکن‌های متوالی در مدت‌زمان کوتاه را فراهم می‌کند.

همه برنامه‌های پس‌زمینه باهم می‌توانند یک‌بار در یک دوره ۳۰ دقیقه‌ای اسکن کنند.

‫Android 10 و بالاتر:

همان محدودیت‌های کاهش سرعت Android 9 اعمال می‌شود. گزینه توسعه‌دهنده جدیدی برای روشن/خاموش کردن محدودسازی برای آزمایش محلی وجود دارد (در گزینه‌های توسعه‌دهنده > شبکه > محدودسازی اسکن Wi-Fi).