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

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

عملية البحث عن شبكات 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()، يجب استيفاء جميع الشروط التالية:

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

الإصدار 10 من نظام التشغيل Android (المستوى 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 دقيقة.

الإصدار 10 من نظام التشغيل Android والإصدارات الأحدث:

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