targetSdkVersion≥26时WifiManager.WifiInfo的getSSID/getBSSID失效求助
关于targetSdkVersion 26+无法获取SSID/BSSID的问题解答
这个问题我之前也碰到过,核心原因是Android 8.0(对应API 26)开始对WiFi信息的获取权限做了重大调整,咱们一步步拆解:
为什么targetSdkVersion升级到26+就出问题了?
从API 26开始,Google收紧了位置相关权限的管控,WiFi的SSID、BSSID这类信息被归类为位置敏感数据,所以获取规则发生了两个关键变化:
- 权限类型变更:之前只需要声明普通权限
ACCESS_WIFI_STATE就能拿到这些信息,但API 26及以上必须申请危险权限——ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION,而且必须得到用户的主动授权,仅靠清单文件声明完全没用。 - 无权限时的默认返回值:当App没有获得位置授权时,系统会返回占位值:SSID固定为
<unknown ssid>,BSSID固定为02:00:00:00:00:00,正好和你遇到的情况匹配。
解决这个问题需要做这些操作
1. 更新清单文件的权限声明
在AndroidManifest.xml中补充位置权限的声明,同时保留原有的WiFi相关权限:
<!-- 原有WiFi权限仍需保留 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 新增位置权限,二选一即可,推荐ACCESS_FINE_LOCATION --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> -->
2. 动态请求位置权限
因为位置权限是危险权限,必须在代码中主动向用户申请授权,不能只靠清单声明。这里给你一段示例代码:
private static final int REQUEST_LOCATION_PERM = 101; // 检查权限并发起请求 private void prepareGetWifiInfo() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // 权限未授予,发起请求 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERM); } else { // 权限已就绪,直接获取WiFi信息 fetchWifiDetails(); } } // 处理权限请求结果 @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信息 fetchWifiDetails(); } else { // 用户拒绝授权,提示无法获取信息 Toast.makeText(this, "需要位置权限才能获取WiFi详情哦", Toast.LENGTH_SHORT).show(); } } } // 实际获取WiFi信息的方法 private void fetchWifiDetails() { WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); String ssid = wifiInfo.getSSID(); String bssid = wifiInfo.getBSSID(); // 这里就可以拿到正确的SSID和BSSID了 }
3. 额外注意事项(针对更高版本)
如果你的App需要在后台状态下获取WiFi信息,在API 29(Android 10)及以上还需要额外申请ACCESS_BACKGROUND_LOCATION权限,同样需要动态请求,并且要向用户清晰说明后台获取的必要性,否则用户大概率会拒绝。
另外,即使拿到了位置权限,如果设备的位置服务被关闭,也可能无法获取到正确的WiFi信息,建议在代码中增加位置服务状态的检查,必要时引导用户打开。
内容的提问来源于stack exchange,提问作者NullPointerException
相关产品推荐
相关产品推荐

