21、WiFi与位置服务:为什么WiFi扫描需要位置权限
这个问题,我几乎每次培训都会被问到。
“我只是想扫个WiFi列表,为什么非要给我弹位置权限?”
嗯,说实话,我第一次接触这个限制时也挺懵的。后来踩过坑、翻过源码,才彻底搞明白——这背后其实是隐私保护的历史遗留问题。
21.1 为什么WiFi扫描和位置绑定在一起?
核心原因很简单:WiFi AP(接入点)的BSSID(MAC地址)本质上是一个位置标识符。
你想想看,Google的街景车满世界跑,就是在收集WiFi信号和GPS坐标的对应关系。只要你的设备扫描到某个AP,就能通过云端数据库反推出你的大致位置。
所以,Android从6.0开始,就把WiFi扫描归入了“位置信息”的范畴。你不给位置权限,系统就不让你拿扫描结果。
核心逻辑:
- WiFi AP的BSSID → 可映射到物理位置
- 扫描结果包含BSSID → 属于位置数据
- 访问位置数据 → 需要位置权限
我在项目中遇到过一位产品经理,坚持认为“扫WiFi和定位是两回事”。我只好打开设置里的WiFi扫描记录给他看——每次扫描,系统都会记录位置变化。他看完就沉默了。
21.2 Android 12+ 的粗略位置权限
Android 12之前,你要扫WiFi,必须申请ACCESS_FINE_LOCATION(精确位置)。这其实有点过度授权了——我只是想知道周围有哪些WiFi,并不需要知道我在哪条街上。
Google自己也意识到了这个问题。所以Android 12引入了粗略位置权限(ACCESS_COARSE_LOCATION)。
我的建议:如果你的App只需要扫描WiFi列表来做网络切换、信号监测,不需要地图定位,那就只申请粗略位置权限。这样用户更容易接受,审核也更容易通过。
但注意,这里有个坑:
我曾经踩过的坑:在Android 12上只申请了粗略位置权限,结果WifiManager.startScan()返回了空列表。排查了半天才发现——某些厂商的定制ROM把粗略权限的WiFi扫描给阉割了。所以,建议在运行时检测扫描结果是否为空,如果为空,提示用户切换到精确位置模式。
权限声明示例:
<!-- AndroidManifest.xml -->
<!-- Android 12+ 推荐使用粗略位置 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 如果需要精确位置(比如地图导航),再加这个 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
运行时请求权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// Android 12+ 可以只请求粗略位置
requestPermissions(
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION),
REQUEST_CODE
)
} else {
// 低版本必须请求精确位置
requestPermissions(
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_CODE
)
}
21.3 WiFi扫描与隐私合规
这块是重灾区。我见过太多App因为WiFi扫描被下架了。
说白了,隐私合规就三条红线:
- 不能偷偷扫:必须在用户同意位置权限后才能开始扫描
- 不能一直扫:后台持续扫描会被系统限制,也会被用户投诉
- 不能乱传数据:扫描到的BSSID、SSID不能随意上传到自己的服务器
合规检查清单:
- ✅ 扫描前检查权限是否已授予
- ✅ 扫描频率控制在30秒以上一次
- ✅ 扫描结果仅用于本地功能(如网络切换)
- ❌ 不要将BSSID上传到第三方分析平台
- ❌ 不要在后台无限制循环扫描
我记得有一次,一个合作方的App在后台每5秒扫一次WiFi,结果被Google Play直接下架。他们找我帮忙,我一看日志——好家伙,一天扫描了17万次。这已经不是技术问题了,是设计问题。
21.4 知识体系总览
下面这张图,是我自己整理的知识结构。每次带新人,我都会先让他们看这张图:
21.5 避坑指南
最后,分享几个我亲身踩过的坑:
- 坑1:在Android 13上,即使有了位置权限,
WifiManager.getScanResults()也可能返回空——因为系统限制了扫描频率。解决方案是监听SCAN_RESULTS_AVAILABLE_ACTION广播,不要主动轮询。 - 坑2:有些国产手机(比如某米、某为)在后台会直接杀掉WiFi扫描线程。我曾经调试了一整天,最后发现是手机管家把App的定位权限给禁了。
- 坑3:隐私合规审核时,Google会检查你的App是否在用户拒绝权限后仍然调用
startScan()。如果检测到,直接拒审。所以一定要做权限拒绝后的降级处理。
我的小技巧:在开发阶段,可以在设置里开启“始终允许位置权限”,避免反复弹窗。但上线前一定要测试“拒绝权限”的场景,确保App不会崩溃。
好了,这一章的内容就到这里。WiFi扫描和位置权限的关系,说白了就是“你扫到的每个AP,都在告诉别人你在哪”。理解了这一点,后面的权限申请、隐私合规就都顺理成章了。
公众号:蓝海资料掘金营,微信deep3321