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

Android中wifiManager.getScanResults()返回空列表问题求助

解决getScanResults()返回空列表的问题

看起来你踩了WiFi扫描最常见的坑之一——把异步操作当成同步来处理,再加上可能忽略了不同Android版本的权限/系统限制,才导致拿到空结果。我帮你一步步梳理问题和解决方案:

核心问题:扫描是异步的,你太早获取结果了

你在onCreate里调用wifiManager.startScan()后,立刻去取wifiReceiver.results,但此时广播接收器还没收到扫描完成的回调,results自然是空的。WiFi扫描是后台异步操作,必须等系统发送SCAN_RESULTS_AVAILABLE_ACTION广播后,才能拿到有效结果。

解决方案1:等待广播回调再处理结果

修改你的广播接收器,通过回调接口把扫描结果传递给Activity,而不是直接在onCreate里硬取。

第一步:给广播接收器添加回调接口

public class WiFiReceiver extends BroadcastReceiver {
    private WifiManager wifiManager;
    private OnScanResultListener listener;

    // 定义回调接口
    public interface OnScanResultListener {
        void onScanSuccess(List<ScanResult> results);
        void onScanFailure();
    }

    public WiFiReceiver(WifiManager wifiManager, OnScanResultListener listener) {
        this.wifiManager = wifiManager;
        this.listener = listener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        boolean success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false);
        if (success) {
            List<ScanResult> results = wifiManager.getScanResults();
            Log.e("wiFi Manager", "扫描完成");
            // 通过回调把结果传给Activity
            if (listener != null) {
                listener.onScanSuccess(results);
            }
        } else {
            Log.e("wiFi Manager", "扫描失败");
            if (listener != null) {
                listener.onScanFailure();
            }
        }
    }
}

第二步:在Activity里实现回调并处理结果

同时补上动态权限申请(Android 6.0+必须做,只在Manifest声明没用):

public class Home extends Activity implements WiFiReceiver.OnScanResultListener {
    Context context;
    WifiManager wifiManager = null;
    WiFiReceiver wifiReceiver = null;

    private static final int PERMISSION_REQUEST_LOCATION = 1001;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home);
        context = this;
        // 先检查权限,再初始化扫描
        checkLocationPermission();
    }

    // 检查并申请位置权限
    private void checkLocationPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    PERMISSION_REQUEST_LOCATION);
        } else {
            initWifiScan();
        }
    }

    // 初始化WiFi扫描逻辑
    private void initWifiScan() {
        wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        wifiReceiver = new WiFiReceiver(wifiManager, this);
        IntentFilter intentFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        registerReceiver(wifiReceiver, intentFilter);
        
        // 确保WiFi已开启(Android 12+不能直接调用setWifiEnabled,需跳转到设置)
        if (!wifiManager.isWifiEnabled()) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
                Toast.makeText(this, "请先开启WiFi", Toast.LENGTH_SHORT).show();
                return;
            } else {
                wifiManager.setWifiEnabled(true);
            }
        }
        
        // 开始扫描
        boolean scanStarted = wifiManager.startScan();
        if (!scanStarted) {
            Log.e("WiFi", "扫描请求被系统拒绝");
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (wifiReceiver != null) {
            unregisterReceiver(wifiReceiver);
        }
    }

    // 处理扫描成功的结果
    @Override
    public void onScanSuccess(List<ScanResult> results) {
        if (results == null || results.isEmpty()) {
            Log.d("WiFi", "扫描结果为空,可能是位置服务未开启或系统限制");
            return;
        }
        // 遍历打印扫描到的WiFi
        for (ScanResult result : results) {
            Log.d("WiFi", String.format("SSID: %s, 信号强度: %d", result.SSID, result.level));
        }
    }

    @Override
    public void onScanFailure() {
        Toast.makeText(this, "WiFi扫描失败", Toast.LENGTH_SHORT).show();
    }

    // 权限申请结果回调
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_LOCATION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                initWifiScan();
            } else {
                Toast.makeText(this, "需要位置权限才能扫描WiFi", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

解决方案2:满足不同Android版本的额外限制

除了代码逻辑,这些系统限制也可能导致扫描结果为空:

  • Android 8.0+:必须开启位置服务(即使权限已申请),可以提示用户跳转到设置开启:
    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
        Toast.makeText(this, "请开启位置服务", Toast.LENGTH_SHORT).show();
    }
    
  • Android 10+:必须使用ACCESS_FINE_LOCATION权限,ACCESS_COARSE_LOCATION不再支持WiFi扫描;且系统会限制短时间内的扫描频率,频繁扫描可能被拒绝。
  • Android 12+:需要额外添加NEARBY_WIFI_DEVICES权限到Manifest(无需动态申请):
    <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
                     android:usesPermissionFlags="neverForLocation" />
    
    如果你的应用需要通过WiFi扫描获取位置,去掉neverForLocation标志即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:55:13