نظرة عامة على البحث عن شبكات Wi-Fi

يمكنك استخدام إمكانات البحث عن شبكات Wi-Fi التي توفّرها واجهة برمجة التطبيقات WifiManager API للحصول على قائمة بنقاط الوصول إلى Wi-Fi المرئية من الجهاز.

عملية البحث عن شبكات Wi-Fi

تتضمّن عملية الفحص ثلاث خطوات:

  1. تسجيل مستمع بث للحدث SCAN_RESULTS_AVAILABLE_ACTION، الذي يتم استدعاؤه عند اكتمال طلبات الفحص، مع توفير حالة النجاح/الفشل. بالنسبة إلى الأجهزة التي تعمل بنظام التشغيل Android 10 (مستوى واجهة برمجة التطبيقات 29) والإصدارات الأحدث، سيتم إرسال رسالة البث هذه لأي عملية فحص كاملة لشبكة Wi-Fi يتم إجراؤها على الجهاز من قِبل النظام الأساسي أو التطبيقات الأخرى. يمكن للتطبيقات الاستماع بشكل غير مباشر إلى جميع عمليات الفحص المكتملة على الجهاز باستخدام البث بدون إجراء عملية فحص خاصة بها.

  2. طلب إجراء عملية فحص باستخدام WifiManager.startScan(). احرص على التحقّق من حالة الإرجاع للطريقة، لأنّ الاستدعاء قد يفشل لأي من الأسباب التالية:

    • قد يتم تقييد طلبات الفحص بسبب إجراء عدد كبير جدًا من عمليات الفحص في فترة قصيرة.
    • الجهاز غير نشِط حاليًا وتم إيقاف الفحص.
    • تُبلغ أجهزة Wi-Fi عن فشل عملية الفحص.
  3. الحصول على نتائج الفحص باستخدام WifiManager.getScanResults(). نتائج الفحص التي يتم عرضها هي النتائج التي تم تعديلها مؤخرًا، وقد تكون من عملية فحص سابقة إذا لم تكتمل عملية الفحص الحالية أو لم تنجح. يعني ذلك أنّه قد يتم عرض نتائج فحص قديمة إذا استدعيت هذه الطريقة قبل تلقّي بث ناجح للحدث SCAN_RESULTS_AVAILABLE_ACTION.

يوضّح الرمز البرمجي التالي مثالاً على كيفية تنفيذ هذه الخطوات:

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

القيود

فرض الإصدار Android 8.0 (المستوى 26 لواجهة برمجة التطبيقات) قيودًا على الأذونات والوتيرة المسموح بها لعمليات البحث عن شبكات Wi-Fi.

لتحسين أداء الشبكة والأمان وعمر البطارية، شدّد الإصدار Android 9 (المستوى 28 لواجهة برمجة التطبيقات) متطلبات الأذونات وقيّد بشكل أكبر وتيرة عمليات فحص شبكات Wi-Fi.

الأذونات

‫Android 8.0 وAndroid 8.1:

يتطلّب استدعاء ناجح لـ WifiManager.getScanResults() الحصول على أيّ من الأذونات التالية:

إذا لم يكن لدى التطبيق الذي يستدعي الطريقة أي من هذه الأذونات، سيفشل الاستدعاء مع ظهور SecurityException.

بدلاً من ذلك، على الأجهزة التي تعمل بنظام التشغيل Android 8.0 (مستوى واجهة برمجة التطبيقات 26) والإصدارات الأحدث، يمكنك استخدام CompanionDeviceManager لإجراء عملية فحص للأجهزة المصاحبة القريبة نيابةً عن تطبيقك بدون الحاجة إلى إذن تحديد الموقع الجغرافي. لمزيد من المعلومات حول هذا الخيار، اطّلِع على مقالة إقران الأجهزة المصاحبة.

‫Android 9:

يتطلّب استدعاء ناجح لـ WifiManager.startScan() استيفاء جميع الشروط التالية:

  • يجب أن يكون لدى تطبيقك إذن ACCESS_FINE_LOCATION أو ACCESS_COARSE_LOCATION.
  • يجب أن يكون لدى تطبيقك إذن CHANGE_WIFI_STATE.
  • يجب تفعيل خدمات الموقع الجغرافي على الجهاز (ضمن الإعدادات > الموقع الجغرافي).

‫Android 10 (مستوى واجهة برمجة التطبيقات 29) والإصدارات الأحدث:

يتطلّب استدعاء ناجح لـ WifiManager.startScan() استيفاء جميع الشروط التالية:

  • إذا كان تطبيقك يستهدف حزمة تطوير البرامج (SDK) لنظام التشغيل Android 10 (المستوى 29 لواجهة برمجة التطبيقات) أو إصدارًا أحدث، يجب أن يكون لدى تطبيقك إذن ACCESS_FINE_LOCATION.
  • إذا كان تطبيقك يستهدف حزمة تطوير برامج (SDK) أقل من Android 10 (المستوى 29 لواجهة برمجة التطبيقات)، يجب أن يكون لدى تطبيقك إذن ACCESS_COARSE_LOCATION أو ACCESS_FINE_LOCATION.
  • يجب أن يكون لدى تطبيقك إذن CHANGE_WIFI_STATE.
  • يجب تفعيل خدمات الموقع الجغرافي على الجهاز (ضمن الإعدادات > الموقع الجغرافي).

لاستدعاء WifiManager.getScanResults() بنجاح، تأكَّد من استيفاء جميع الشروط التالية:

  • إذا كان تطبيقك يستهدف حزمة تطوير البرامج (SDK) لنظام التشغيل Android 10 (المستوى 29 لواجهة برمجة التطبيقات) أو إصدارًا أحدث، يجب أن يكون لدى تطبيقك إذن ACCESS_FINE_LOCATION.
  • إذا كان تطبيقك يستهدف حزمة تطوير برامج (SDK) أقل من Android 10 (المستوى 29 لواجهة برمجة التطبيقات)، يجب أن يكون لدى تطبيقك إذن ACCESS_COARSE_LOCATION أو ACCESS_FINE_LOCATION.
  • يجب أن يكون لدى تطبيقك إذن ACCESS_WIFI_STATE.
  • يجب تفعيل خدمات الموقع الجغرافي على الجهاز (ضمن الإعدادات > الموقع الجغرافي).

إذا لم يستوفِ التطبيق الذي يستدعي الطريقة جميع هذه المتطلبات، سيفشل الاستدعاء مع ظهور SecurityException.

تقييد

تنطبق القيود التالية على وتيرة عمليات الفحص باستخدام WifiManager.startScan().

‫Android 8.0 وAndroid 8.1:

يمكن لكل تطبيق قيد التشغيل في الخلفية إجراء عملية فحص واحدة خلال فترة 30 دقيقة.

‫Android 9:

يمكن لكل تطبيق يعمل في المقدّمة إجراء أربع عمليات فحص خلال فترة دقيقتَين. يسمح ذلك بإجراء عدد كبير من عمليات الفحص في فترة قصيرة.

يمكن لجميع التطبيقات قيد التشغيل في الخلفية مجتمعةً إجراء عملية فحص واحدة خلال فترة 30 دقيقة.

‫Android 10 والإصدارات الأحدث:

تنطبق حدود التقييد نفسها من Android 9. يتوفّر خيار جديد للمطوّرين لإيقاف التقييد مؤقتًا لإجراء الاختبار المحلي (ضمن خيارات المطوّرين > الشبكات > تقييد عمليات فحص شبكات Wi-Fi).