Android WiFi扫描

Wifi扫描

Wifi scanning overview

权限方面

必须权限如下:

  • 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扫描的实现步骤

  1. 注册系统广播接收器,触发扫描动作【WifiManager.startScan()】
  2. 系统扫描结束后会发送广播,等待接收广播
  3. 收到广播后,获取扫描结果【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)

你可能感兴趣的:(Android)