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