Bạn có thể sử dụng tính năng quét tìm Wi-Fi do API WifiManager để nhận danh sách Các điểm truy cập Wi-Fi mà thiết bị nhìn thấy.
Quá trình quét tìm Wi-Fi
Quá trình quét có ba bước:
Đăng ký trình nghe truyền tin cho
SCAN_RESULTS_AVAILABLE_ACTION
! được gọi khi yêu cầu quét được hoàn tất, cung cấp trạng thái thành công/thất bại. Đối với các thiết bị chạy Android 10 (API cấp 29) trở lên, giá trị này sẽ được gửi đi để quét toàn bộ Wi-Fi trên thiết bị bằng cách nền tảng hoặc các ứng dụng khác. Các ứng dụng có thể nghe thụ động tất cả các bản quét hoàn thành trên thiết bị bằng cách sử dụng thông báo truyền tin mà không quét của bạn.Yêu cầu quét bằng
WifiManager.startScan()
. Hãy nhớ kiểm tra trạng thái trả về của phương thức này, vì lệnh gọi có thể không thành công vì bất kỳ lý do nào sau đây:- Yêu cầu quét có thể bị điều tiết do có quá nhiều lần quét trong một thời gian ngắn.
- Thiết bị ở trạng thái rảnh và tính năng quét đã tắt.
- Phần cứng Wi-Fi báo cáo lỗi quét.
Nhận kết quả quét bằng
WifiManager.getScanResults()
. Kết quả quét được trả về là kết quả được cập nhật gần đây nhất, có thể từ lần quét trước nếu lần quét hiện tại chưa hoàn tất hoặc thành công. Điều này có nghĩa là bạn có thể nhận được các kết quả quét cũ hơn nếu gọi phương thức này trước khi nhận được thông báo thành côngSCAN_RESULTS_AVAILABLE_ACTION
truyền tin.
Mã sau đây cung cấp ví dụ về cách triển khai các bước này:
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 ... }
Quy định hạn chế
Android 8.0 (API cấp 26) đưa ra những hạn chế về quyền và tần suất quét tìm Wi-Fi được phép.
Để cải thiện hiệu suất mạng, tính bảo mật và thời lượng pin, Android 9 (API) cấp 28) thắt chặt các yêu cầu về quyền và hạn chế hơn nữa tần suất Quét tìm Wi-Fi.
Quyền
Android 8.0 và Android 8.1:
Cuộc gọi thành công đến
WifiManager.getScanResults()
yêu cầu bất kỳ quyền nào trong số các quyền sau đây:
Nếu ứng dụng gọi không có bất kỳ quyền nào trong số này, thì cuộc gọi sẽ không thực hiện được
SecurityException
.
Ngoài ra, trên thiết bị chạy Android 8.0 (API cấp 26) trở lên, bạn có thể
sử dụng
CompanionDeviceManager
để quét các thiết bị đồng hành ở gần thay mặt cho ứng dụng của bạn mà không
yêu cầu quyền truy cập thông tin vị trí. Để biết thêm về lựa chọn này, hãy xem
Thiết bị đồng hành
ghép nối.
Android 9:
Cuộc gọi thành công đến
WifiManager.startScan()
yêu cầu đáp ứng tất cả các điều kiện sau:
- Ứng dụng của bạn có
ACCESS_FINE_LOCATION
hoặcACCESS_COARSE_LOCATION
quyền. - Ứng dụng của bạn có
CHANGE_WIFI_STATE
quyền. - Dịch vụ vị trí đã được bật trên thiết bị (trong Cài đặt > Vị trí).
Android 10 (API cấp 29) trở lên:
Cuộc gọi thành công đến
WifiManager.startScan()
yêu cầu đáp ứng tất cả các điều kiện sau:
- Nếu ứng dụng của bạn nhắm đến SDK Android 10 (API cấp 29) trở lên, thì ứng dụng đó
có
ACCESS_FINE_LOCATION
quyền. - Nếu ứng dụng của bạn nhắm đến SDK thấp hơn Android 10 (API cấp 29), thì ứng dụng đó
có
ACCESS_COARSE_LOCATION
hoặcACCESS_FINE_LOCATION
quyền. - Ứng dụng của bạn có
CHANGE_WIFI_STATE
quyền. - Dịch vụ vị trí đã được bật trên thiết bị (trong Cài đặt > Vị trí).
Để gọi thành công
WifiManager.getScanResults()
!
đảm bảo đáp ứng tất cả các điều kiện sau:
- Nếu ứng dụng của bạn nhắm đến SDK Android 10 (API cấp 29) trở lên, thì ứng dụng đó
có quyền
ACCESS_FINE_LOCATION
. - Nếu ứng dụng của bạn nhắm đến SDK thấp hơn Android 10 (API cấp 29), thì ứng dụng đó
có quyền
ACCESS_COARSE_LOCATION
hoặcACCESS_FINE_LOCATION
. - Ứng dụng của bạn có
ACCESS_WIFI_STATE
quyền. - Dịch vụ vị trí đã được bật trên thiết bị (trong Cài đặt > Vị trí).
Nếu ứng dụng gọi không đáp ứng tất cả các yêu cầu này, thì cuộc gọi sẽ không thực hiện được với
SecurityException
.
Điều tiết
Các giới hạn sau áp dụng cho tần suất quét sử dụng
WifiManager.startScan()
.
Android 8.0 và Android 8.1:
Mỗi ứng dụng ở chế độ nền có thể quét một lần trong khoảng thời gian 30 phút.
Android 9:
Mỗi ứng dụng trên nền trước có thể quét 4 lần trong vòng 2 phút. Điều này cho phép hàng loạt lần quét trong một thời gian ngắn.
Tất cả các ứng dụng nền kết hợp lại có thể quét một lần trong khoảng thời gian 30 phút.
Android 10 trở lên:
Các giới hạn điều tiết tương tự như trên Android 9. Có một lựa chọn mới cho nhà phát triển để tắt chế độ điều tiết đối với kiểm thử cục bộ (trong Tuỳ chọn cho nhà phát triển > Kết nối mạng > Điều tiết quá trình quét Wi-Fi).