คุณสามารถใช้ความสามารถในการสแกน Wi-Fi ที่ WifiManager API มีให้เพื่อดูรายการจุดเข้าใช้งาน Wi-Fi ที่มองเห็นได้จากอุปกรณ์
ขั้นตอนการสแกนหา Wi-Fi
กระบวนการสแกนมี 3 ขั้นตอนดังนี้
ลงทะเบียน Listener แบบออกอากาศสําหรับ
SCAN_RESULTS_AVAILABLE_ACTION
ซึ่งจะเรียกใช้เมื่อคําขอสแกนเสร็จสมบูรณ์ โดยจะระบุสถานะความสําเร็จ/ความล้มเหลว สำหรับอุปกรณ์ที่ใช้ Android 10 (API ระดับ 29) ขึ้นไป การส่งข้อมูลนี้จะส่งไปสแกนหา Wi-Fi เต็มรูปแบบที่แพลตฟอร์มหรือแอปอื่นๆ ดำเนินการในอุปกรณ์ แอปสามารถฟังการสแกนทั้งหมดที่เสร็จสมบูรณ์ในอุปกรณ์ได้โดยใช้การออกอากาศโดยไม่ต้องทำการสแกนเองขอการสแกนโดยใช้
WifiManager.startScan()
อย่าลืมตรวจสอบสถานะการคืนค่าของเมธอด เนื่องจากการเรียกอาจไม่สําเร็จเนื่องจากสาเหตุใดสาเหตุหนึ่งต่อไปนี้- ระบบอาจควบคุมคำขอสแกนเนื่องจากมีการสแกนจำนวนมากเกินไปในช่วงเวลาสั้นๆ
- อุปกรณ์ไม่มีการใช้งานและการสแกนปิดอยู่
- ฮาร์ดแวร์ Wi-Fi รายงานการสแกนไม่สำเร็จ
ดูผลการสแกนโดยใช้
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 (API ระดับ 26) เพิ่มข้อจำกัดเกี่ยวกับสิทธิ์และความถี่ของการสแกนหา Wi-Fi ที่อนุญาต
Android 9 (API ระดับ 28) ได้ปรับให้ข้อกำหนดด้านสิทธิ์ที่เข้มงวดขึ้นและจำกัดความถี่ในการสแกนหา Wi-Fi เพื่อปรับปรุงประสิทธิภาพของเครือข่าย ความปลอดภัย และอายุการใช้งานแบตเตอรี่
สิทธิ์
Android 8.0 และ Android 8.1:
การเรียกใช้ WifiManager.getScanResults()
ที่สำเร็จต้องใช้สิทธิ์ต่อไปนี้อย่างน้อย 1 สิทธิ์
หากแอปโทรไม่มีสิทธิ์เหล่านี้ การโทรจะดำเนินการไม่สำเร็จพร้อมด้วย SecurityException
หรือในอุปกรณ์ที่ใช้ Android 8.0 (API ระดับ 26) ขึ้นไป คุณสามารถใช้ CompanionDeviceManager
เพื่อสแกนอุปกรณ์ที่ใช้งานร่วมกันที่อยู่ใกล้เคียงในนามของแอปได้โดยไม่ต้องขอสิทธิ์เข้าถึงตำแหน่ง ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกนี้ได้ที่หัวข้อการจับคู่อุปกรณ์เสริม
Android 9:
การเรียกใช้ WifiManager.startScan()
ที่สำเร็จต้องเป็นไปตามเงื่อนไขทั้งหมดต่อไปนี้
- แอปของคุณมีสิทธิ์
ACCESS_FINE_LOCATION
หรือACCESS_COARSE_LOCATION
- แอปของคุณมีสิทธิ์
CHANGE_WIFI_STATE
- มีการเปิดใช้บริการตำแหน่งในอุปกรณ์ (ในส่วนการตั้งค่า > ตำแหน่ง)
Android 10 (API ระดับ 29) ขึ้นไป ให้ทำดังนี้
การเรียกใช้ WifiManager.startScan()
ให้สำเร็จต้องเป็นไปตามเงื่อนไขต่อไปนี้ทั้งหมด
- หากแอปกําหนดเป้าหมายเป็น Android 10 (API ระดับ 29) SDK ขึ้นไป แสดงว่าแอปมีสิทธิ์
ACCESS_FINE_LOCATION
- หากแอปกำหนดเป้าหมายเป็น SDK ต่ำกว่า Android 10 (API ระดับ 29) แอปของคุณต้องมีสิทธิ์
ACCESS_COARSE_LOCATION
หรือACCESS_FINE_LOCATION
- แอปของคุณมีสิทธิ์
CHANGE_WIFI_STATE
- บริการตำแหน่งเปิดอยู่ในอุปกรณ์ (ในส่วนการตั้งค่า > ตำแหน่ง)
หากต้องการโทรWifiManager.getScanResults()
ให้สำเร็จ ให้ตรวจสอบว่าเป็นไปตามเงื่อนไขต่อไปนี้ทั้งหมด
- หากแอปกําหนดเป้าหมายเป็น Android 10 (API ระดับ 29) SDK ขึ้นไป แอปของคุณจะมีสิทธิ์
ACCESS_FINE_LOCATION
- หากแอปกำหนดเป้าหมายเป็น SDK ต่ำกว่า Android 10 (API ระดับ 29) แอปจะมีสิทธิ์
ACCESS_COARSE_LOCATION
หรือACCESS_FINE_LOCATION
- แอปของคุณมีสิทธิ์
ACCESS_WIFI_STATE
- มีการเปิดใช้บริการตำแหน่งในอุปกรณ์ (ในส่วนการตั้งค่า > ตำแหน่ง)
หากแอปโทรไม่เป็นไปตามข้อกำหนดข้างต้นทั้งหมด จะโทรด้วยSecurityException
ไม่ได้
การควบคุม
ข้อจำกัดต่อไปนี้มีผลกับความถี่ในการสแกนโดยใช้ WifiManager.startScan()
Android 8.0 และ Android 8.1:
แอปที่ทำงานอยู่เบื้องหลังแต่ละแอปจะสแกนได้ 1 ครั้งในระยะเวลา 30 นาที
Android 9:
แอปที่ทำงานอยู่เบื้องหน้าแต่ละแอปจะสแกนได้ 4 ครั้งในระยะเวลา 2 นาที ซึ่งช่วยให้การสแกนเกิดขึ้นได้อย่างรวดเร็วในเวลาสั้นๆ
แอปทั้งหมดที่ทำงานอยู่เบื้องหลังจะสแกนได้ 1 ครั้งในระยะเวลา 30 นาที
Android 10 ขึ้นไป:
โดยจะใช้ขีดจํากัดการจำกัดเดียวกันกับ Android 9 มีตัวเลือกใหม่สำหรับนักพัฒนาแอปในการปิดการควบคุมปริมาณสำหรับการทดสอบในเครื่อง (ในส่วนตัวเลือกสำหรับนักพัฒนาแอป > การทํางานของเครือข่าย > การควบคุมปริมาณการสแกน Wi-Fi)