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