使用Kotlin获取WiFi扫描结果列表遇问题求助
Hey there! Let's dig into why your WiFi scan broadcast receiver isn't firing in Kotlin—since you had this working in Java, it's almost certainly a small oversight or Kotlin-specific setup step you missed. Here are the most common fixes to check:
1. You're Missing Dynamic Permission Requests
Even if you've added ACCESS_FINE_LOCATION and ACCESS_WIFI_STATE to your AndroidManifest.xml, Android 6.0 (API 23) and higher require runtime permissions for location access. WiFi scans rely on location permissions (yes, even if GPS is off), so if you don't request these dynamically, the scan will silently fail.
Here's how to implement dynamic permission requests in Kotlin using the Activity Result API:
private val requestPermissionsLauncher = registerForActivityResult( ActivityResultContracts.RequestMultiplePermissions() ) { permissions -> val isLocationGranted = permissions[Manifest.permission.ACCESS_FINE_LOCATION] ?: false val isWifiStateGranted = permissions[Manifest.permission.ACCESS_WIFI_STATE] ?: false if (isLocationGranted && isWifiStateGranted) { // Permissions granted, start your WiFi scan startWifiScan() } else { // Show a message asking users to enable permissions Toast.makeText(this, "Permissions required to scan WiFi", Toast.LENGTH_SHORT).show() } } // Call this when you want to start scanning (e.g., in onCreate or a button click) fun requestPermissions() { requestPermissionsLauncher.launch( arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_WIFI_STATE ) ) }
2. You're Using Static Broadcast Registration (Android 8.0+)
Starting with Android 8.0 (API 26), most implicit broadcasts (including WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) cannot be registered statically in the manifest. If you tried to register your receiver in AndroidManifest.xml, it won't receive the broadcast. You must register it dynamically in your Activity/Fragment.
Here's how to dynamically register the receiver in Kotlin:
private val wifiScanReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val success = intent?.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false) ?: false if (success) { // Scan results are ready—fetch them here fetchWifiScanResults() } else { // Scan failed, handle error Toast.makeText(context, "WiFi scan failed", Toast.LENGTH_SHORT).show() } } } private lateinit var wifiManager: WifiManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager // Register the receiver val intentFilter = IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) registerReceiver(wifiScanReceiver, intentFilter) } override fun onDestroy() { super.onDestroy() // Don't forget to unregister the receiver to avoid memory leaks unregisterReceiver(wifiScanReceiver) } private fun fetchWifiScanResults() { val scanResults = wifiManager.scanResults // Process your scan results here scanResults.forEach { result -> Log.d("WiFi Scan", "SSID: ${result.SSID}, RSSI: ${result.level}") } } private fun startWifiScan() { val isScanSuccess = wifiManager.startScan() if (!isScanSuccess) { // Scan failed—check permissions or device settings Toast.makeText(this, "Failed to start WiFi scan", Toast.LENGTH_SHORT).show() } }
3. Location Services Are Disabled on the Device
Many Android devices block WiFi scans if location services are turned off, even if you have the correct permissions. Ask your users to enable location services (they don't need to turn on GPS, just the general location toggle) to allow WiFi scanning.
4. Android 10+ Background Scan Restrictions
If you're trying to scan WiFi while your app is in the background, Android 10 (API 29) and higher require the ACCESS_BACKGROUND_LOCATION permission (both in the manifest and dynamically requested). If your app isn't in the foreground and you don't have this permission, the scan won't trigger the broadcast.
Quick Checklist to Verify
- You've requested
ACCESS_FINE_LOCATIONandACCESS_WIFI_STATEdynamically - Your broadcast receiver is registered dynamically (not statically in manifest)
- You're calling
wifiManager.startScan()after permissions are granted - Location services are enabled on the test device
- For Android 10+, you have
ACCESS_BACKGROUND_LOCATIONif scanning in background
Give these steps a try—chances are one of these fixes will get your onReceive() function firing again!
内容的提问来源于stack exchange,提问作者Tommy Jackson

