You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:WiFi扫描结果存入ArrayList时异步返回空列表问题

嘿,我完全懂你碰到的这个坑——WiFi扫描是异步操作,你的方法在广播接收器拿到扫描结果之前就已经返回了,所以才会出现onReceive里能打印出数据,但返回的ArrayList却空无一物的情况。

问题根源拆解

调用wifiManager.startScan()后,系统并不会立刻返回扫描结果,而是会在扫描完成后通过WifiManager.SCAN_RESULTS_AVAILABLE_ACTION这个广播来通知你。如果你的方法是同步返回ArrayList,那肯定会“抢跑”——广播还没触发,列表自然是空的。

解决方案:用回调/观察者模式等待结果

最靠谱的方式是放弃“直接返回ArrayList”的思路,改用回调接口或者LiveData来接收异步返回的扫描结果。这里给你举个回调的实现例子:

1. 定义一个扫描结果回调接口

interface WifiScanCallback {
    fun onScanSuccess(results: ArrayList<ScanResult>)
    fun onScanFailed()
}

2. 重构扫描方法,传入回调

fun scanWifi(context: Context, callback: WifiScanCallback) {
    val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
    val scanFilter = IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)

    // 创建临时广播接收器
    val scanReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent?.action == WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) {
                // 检查扫描是否成功更新
                val isUpdated = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
                if (isUpdated) {
                    // 拿到扫描结果,转成ArrayList
                    val scanResults = ArrayList(wifiManager.scanResults)
                    callback.onScanSuccess(scanResults)
                } else {
                    callback.onScanFailed()
                }
                // 扫描完成后立刻注销接收器,避免内存泄漏
                context?.unregisterReceiver(this)
            }
        }
    }

    // 注册接收器,然后启动扫描
    context.registerReceiver(scanReceiver, scanFilter)
    val scanStarted = wifiManager.startScan()
    
    // 如果扫描启动失败,直接回调失败并注销接收器
    if (!scanStarted) {
        context.unregisterReceiver(scanReceiver)
        callback.onScanFailed()
    }
}

3. 调用扫描方法,在回调里处理结果

// 比如在Activity里调用
scanWifi(this, object : WifiScanCallback {
    override fun onScanSuccess(results: ArrayList<ScanResult>) {
        // 这里的results就是填充好的扫描结果列表啦!
        Log.i("WiFi扫描", "拿到${results.size}条结果")
        // 后续可以更新UI、存储数据等
    }

    override fun onScanFailed() {
        Log.e("WiFi扫描", "扫描启动失败,请检查权限和WiFi状态")
    }
})

必加的权限提醒

别忘了在AndroidManifest.xml里声明权限,Android 6.0+还要动态申请位置权限(因为扫描WiFi需要位置服务支持):

<!-- WiFi基础权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- Android 6.0+ 位置权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

另外,Android 10及以上的设备,需要用户开启位置服务才能正常扫描到WiFi热点哦。

内容的提问来源于stack exchange,提问作者Frankie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:38:32