Android 6.0无法显示WiFi扫描结果求助(Android 5.0正常)
解决Android 6.0及以上WiFi扫描无结果的问题
哥们,你碰到的这个问题其实是Android 6.0(API 23)权限机制变更导致的核心问题——WiFi扫描需要位置权限,而6.0开始危险权限必须动态申请,5.0只需要在Manifest里声明就行,所以才会出现版本差异。下面给你一步步搞定:
1. 补全Manifest权限
首先在AndroidManifest.xml里把需要的权限都加上,覆盖WiFi相关、位置权限,以及Android 12+的新WiFi权限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Android 12+ 额外需要 --> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2. 动态申请位置权限(关键步骤!)
6.0+系统不会自动授予危险权限,必须在运行时弹窗让用户同意。在你的ScanWifList Activity里添加这些代码:
private static final int REQUEST_LOCATION_PERM = 1001; private WifiManager mainWifiObj; private BroadcastReceiver wifiReceiver; // 检查是否已获取位置权限 private boolean hasLocationPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { int coarsePerm = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION); int finePerm = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION); return coarsePerm == PackageManager.PERMISSION_GRANTED || finePerm == PackageManager.PERMISSION_GRANTED; } // 低于6.0版本默认拥有权限 return true; } // 向用户请求位置权限 private void askForLocationPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERM); } } // 处理权限申请结果 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_LOCATION_PERM) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限获取成功,启动WiFi扫描 startWifiScan(); } else { // 用户拒绝权限,给出提示 Toast.makeText(this, "没有位置权限无法扫描WiFi网络", Toast.LENGTH_SHORT).show(); } } }
3. 修改扫描逻辑:先鉴权再扫描
把原来的扫描流程调整为先检查权限,再执行扫描,避免无权限时扫描无效:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 初始化WiFi管理器 mainWifiObj = (WifiManager) getSystemService(Context.WIFI_SERVICE); // 先校验权限 if (hasLocationPermission()) { startWifiScan(); } else { askForLocationPermission(); } } // 启动WiFi扫描的核心方法 private void startWifiScan() { // 确保WiFi处于开启状态 if (!mainWifiObj.isWifiEnabled()) { mainWifiObj.setWifiEnabled(true); } // 注册广播接收器接收扫描结果 wifiReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { boolean isScanReady = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false); if (isScanReady) { // 获取扫描到的WiFi列表 List<ScanResult> scanResults = mainWifiObj.getScanResults(); // 将结果绑定到ListView的适配器(替换成你自己的适配器类) setListAdapter(new YourWifiListAdapter(ScanWifList.this, scanResults)); } } }; registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); // 触发扫描 mainWifiObj.startScan(); } // 销毁Activity时注销广播,避免内存泄漏 @Override protected void onDestroy() { super.onDestroy(); if (wifiReceiver != null) { unregisterReceiver(wifiReceiver); } }
额外注意事项
- Android 12(API 31)及以上,若仅需扫描WiFi无需连接,可使用
NEARBY_WIFI_DEVICES权限替代位置权限,但需在Manifest里给该权限添加android:usesPermissionFlags="neverForLocation"属性,同时将targetSdkVersion设为31+。 - 部分设备的系统要求必须打开系统位置服务开关(不是应用权限)才能扫描WiFi,如果仍无结果,可以提示用户前往系统设置开启位置服务。
内容的提问来源于stack exchange,提问作者pravin maske




