คุณสามารถใช้ความสามารถในการสแกนหา Wi-Fi ใน WifiManager API เพื่อดูรายการ จุดเข้าใช้งาน Wi-Fi ที่มองเห็นได้จากอุปกรณ์
ขั้นตอนการสแกนหา Wi-Fi
กระบวนการสแกนมี 3 ขั้นตอนดังนี้
ลงทะเบียนผู้ฟังการประกาศสำหรับ
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()
ต้องใช้สิทธิ์อย่างใดอย่างหนึ่งต่อไปนี้
หากแอปการโทรไม่มีสิทธิ์ดังกล่าว จะโทรไม่สำเร็จ
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)