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)
注意:以上是官方文档的说明,与实际测试的结果有出入,可能是手机厂商修改rom导致。
实际测试结果
6.0开始,有如下要求:
必须有至少一个定位权限(ACCESS_FINE_LOCATION / ACCESS_COARSE_LOCATION)
(Nexus7 6.0.1不开定位拿不到)
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)