Wifi扫描
权限方面
必须权限如下:
- ACCESS_WIFI_STATE(用于扫描结束后读取wifi信息)
- CHANGE_WIFI_STATE(用于扫描WiFi列表)
除必须权限外,根据系统版本,还有不同的限制。具体如下
Android 8.0 & 8.1
WifiManager.getScanResults()
方法的调用必须具备以下任一权限:
- ACCESS_FINE_LOCATION
- ACCESS_COARSE_LOCATION
- CHANGE_WIFI_STATE
事实上,从6.0开始,
WifiManager.getScanResults()
方法就需要定位权限了。见[硬件标识符访问权]
否则会抛异常SecurityException
。
Android 9.0
WifiManager.startScan()
方法的调用必须满足以下所有条件:
- 拥有 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 权限
- 拥有 CHANGE_WIFI_STATE 权限
- 打开定位服务
否则会抛异常SecurityException
。
Android Q & later
- 在9.0版限制的基础上,对定位的要求升级为:必须拥有精确定位权限(ACCESS_FINE_LOCATION)
频率方面
Android对WifiManager.startScan()
的调用频率进行了限制。对于超过此频率的接口访问,WifiManager
不会执行完整扫描,而是提供上次扫描所缓存的结果。
Android 8.0 & 8.1
- 每个后台应用:1次/30分钟
Android 9.0 & later
- 每个前台应用:4次/2分钟
- 所有后台应用加起来:1次/30分钟
WiFi扫描的实现步骤
- 注册系统广播接收器,触发扫描动作【WifiManager.startScan()】
- 系统扫描结束后会发送广播,等待接收广播
- 收到广播后,获取扫描结果【WifiManager.getScanResults()】
扫描耗时统计
厂商 | 机型 | 系统 | 扫描个数 | 耗时(ms) |
---|---|---|---|---|
三星 | Note 3 | 5.0 | 26 | 4034 |
三星 | Galaxy A7 | 6.0 | 21 | 1111 |
三星 | S6 | 7.0 | 39 | 2302 |
三星 | S7 | 8.0 | 5 | 1411 |
三星 | S8 plus | 9.0 | 50 | 1467 |
谷歌 | Pixel 2 xl | Q | 37 | 2233 |
魅族 | M5 Note | 6.0 | 18 | 5576 |
魅族 | M15 | 7.1.2 | 61 | 2480 |
华为 | 荣耀 畅玩4X | 5.0 | 1 | 305 |
华为 | MT7-TL10 | 6.0 | 74 | 2531 |
华为 | Mate8 | 7.0 | 4 | 2232 |
华为 | 荣耀V9 | 8.0 | 3 | 1238 |
华为 | 畅享7S | 9.0 | 6 | 605 |
OPPO | R7s | 5.1 | 3 | 960 |
OPPO | R9S plus | 6.0 | 3 | 2636 |
OPPO | R11 | 7.1.1 | 46 | 1551 |
小米 | MI PAD 2 | 5.1 | 66 | 4423 |
小米 | RedMi Note4x | 6.0 | 170 | 5086 |
VIVO | Y51A | 5.0 | 1 | 830 |
VIVO | Y55A | 6.0 | 9 | 1185 |
VIVO | X9 | 7.1 | 10 | 2802 |
VIVO | Y97 | 8.1 | 5 | 2668 |
VIVO | X21i A | 9.0 | 17 | 1181 |
平均值:2211
总结
wifi扫描有两个必须权限:
- ACCESS_WIFI_STATE(用于扫描结束后读取wifi信息)
- CHANGE_WIFI_STATE(用于扫描WiFi列表)
另外,随着Android系统的升级,对WiFi扫描做了越来越严格的限制。系统对 WifiManager.getScanResults()
和 WifiManager.startScan()
所做的限制不太一样,但若要实现一个完整的WiFi扫描,就需要“扫描+获取”两个步骤,因此综合来看,WiFi扫描的行为变化如下:
6.0开始
- 需要至少一个定位权限
8.0开始
- 需要以下权限中至少一个:
- ACCESS_FINE_LOCATION
- ACCESS_COARSE_LOCATION
- CHANGE_WIFI_STATE
9.0开始
需要同时满足以下所有条件:
- 拥有 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 权限
- 拥有 CHANGE_WIFI_STATE 权限
- 打开定位服务
Q开始
- 在9.0版限制的基础上,对定位的要求升级为:必须拥有精确定位权限(ACCESS_FINE_LOCATION)
<font color='red'>注意:以上是官方文档的说明,与实际测试的结果有出入,可能是手机厂商修改rom导致。</font>
实际测试结果
- 6.0开始,有如下要求:
- 必须有至少一个定位权限(ACCESS_FINE_LOCATION / ACCESS_COARSE_LOCATION)</br>
(Nexus7 6.0.1不开定位拿不到)
- 必须有至少一个定位权限(ACCESS_FINE_LOCATION / ACCESS_COARSE_LOCATION)</br>
- 7.1.1开始,有如下要求:
- 必须有至少一个定位权限(ACCESS_FINE_LOCATION / ACCESS_COARSE_LOCATION)
- 必须有 CHANGE_WIFI_STATE 权限
- 必须开启定位服务(魅族M15 、oppo A83)
(小米MIX2 8.0,三星N9600 8.1.0下,不开定位服务也能获取到WiFi列表)
- Q开始,有如下要求:
- 必须有精确定位权限(ACCESS_FINE_LOCATION)
网友评论