वाई-फ़ाई स्कैनिंग की खास जानकारी

डिवाइस से दिखने वाले वाई-फ़ाई ऐक्सेस पॉइंट की सूची पाने के लिए, WifiManager API की मदद से वाई-फ़ाई स्कैन करने की सुविधाओं का इस्तेमाल किया जा सकता है.

वाई-फ़ाई स्कैन करने की प्रोसेस

स्कैन करने की प्रोसेस के तीन चरण होते हैं:

  1. ब्रॉडकास्ट लिसनर रजिस्टर करता है. यह SCAN_RESULTS_AVAILABLE_ACTION के लिए होता है. इसे स्कैन के अनुरोध पूरे होने पर कॉल किया जाता है. इससे अनुरोध के पूरा होने या न होने की स्थिति के बारे में पता चलता है. Android 10 (एपीआई लेवल 29) और इसके बाद के वर्शन वाले डिवाइसों पर, यह ब्रॉडकास्ट तब भेजा जाएगा, जब प्लैटफ़ॉर्म या अन्य ऐप्लिकेशन डिवाइस पर पूरा वाई-फ़ाई स्कैन करेंगे. ऐप्लिकेशन, ब्रॉडकास्ट का इस्तेमाल करके डिवाइस पर स्कैन पूरा होने की सभी सूचनाएं सुन सकते हैं. इसके लिए, उन्हें खुद स्कैन करने की ज़रूरत नहीं होती.

  2. WifiManager.startScan() का इस्तेमाल करके, स्कैन करने का अनुरोध करें. तरीके के लिए सामान लौटाने की स्थिति देखना न भूलें, क्योंकि कॉल इनमें से किसी भी वजह से फ़ेल हो सकता है:

    • कुछ ही समय में कई बार स्कैन करने की वजह से, स्कैन के अनुरोधों को थ्रॉटल किया जा सकता है.
    • डिवाइस का इस्तेमाल नहीं किया जा रहा है और स्कैनिंग की सुविधा बंद है.
    • वाई-फ़ाई हार्डवेयर, स्कैन पूरा न होने की सूचना देता है.
  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) में, अनुमतियों और वाई-फ़ाई स्कैन की अनुमति वाली फ़्रीक्वेंसी से जुड़ी पाबंदियां लागू की गई हैं.

नेटवर्क की परफ़ॉर्मेंस, सुरक्षा, और बैटरी लाइफ़ को बेहतर बनाने के लिए, Android 9 (एपीआई लेवल 28) ने अनुमति से जुड़ी ज़रूरी शर्तों को और सख्त कर दिया है. साथ ही, वाई-फ़ाई स्कैन करने की फ़्रीक्वेंसी को और कम कर दिया है.

अनुमतियां

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() को कॉल करने के लिए, यहां दी गई सभी शर्तें पूरी होनी चाहिए:

  • अगर आपका ऐप्लिकेशन, Android 10 (एपीआई लेवल 29) SDK टूल या इसके बाद के वर्शन को टारगेट करता है, तो आपके ऐप्लिकेशन के पास ACCESS_FINE_LOCATION अनुमति है.
  • अगर आपका ऐप्लिकेशन, Android 10 (एपीआई लेवल 29) से पहले के एसडीके को टारगेट कर रहा है, तो आपके ऐप्लिकेशन के पास ACCESS_COARSE_LOCATION या ACCESS_FINE_LOCATION अनुमति होनी चाहिए.
  • आपके ऐप्लिकेशन के पास CHANGE_WIFI_STATE की अनुमति है.
  • डिवाइस पर जगह की जानकारी की सेवाएं चालू हों (सेटिंग > जगह की जानकारी में जाकर देखें).

WifiManager.getScanResults() को कॉल करने के लिए, पक्का करें कि ये सभी शर्तें पूरी हों:

  • अगर आपका ऐप्लिकेशन, Android 10 (एपीआई लेवल 29) SDK टूल या इसके बाद के वर्शन को टारगेट करता है, तो आपके ऐप्लिकेशन के पास ACCESS_FINE_LOCATION अनुमति होनी चाहिए.
  • अगर आपका ऐप्लिकेशन, 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 में लागू थ्रॉटलिंग की सीमाएं लागू होती हैं. डेवलपर के लिए एक नया विकल्प उपलब्ध है. इसकी मदद से, लोकल टेस्टिंग के लिए थ्रॉटलिंग को टॉगल करके बंद किया जा सकता है. यह विकल्प, डेवलपर के लिए सेटिंग और टूल > नेटवर्किंग > वाई-फ़ाई स्कैन थ्रॉटलिंग में जाकर ऐक्सेस किया जा सकता है.