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

يمكنك استخدام إمكانات البحث عن شبكات Wi-Fi التي توفّرها واجهة برمجة تطبيقات WifiManager للحصول على قائمة بنقاط وصول 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.

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

نظام التشغيل Android 9:

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

نظام التشغيل 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).