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(无需动态申请):
如果你的应用需要通过WiFi扫描获取位置,去掉<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" />neverForLocation标志即可。
内容的提问来源于stack exchange,提问作者Simone Benzi
相关产品推荐
相关产品推荐

