Android wifi信号强度显示流程

  • 1. RSSI
  • 2. 从wpa_supplicant获取RSSI
  • 3. framework层对wifi信号强度的处理
  • 4. StatusBar 更新wifi信号强度
  • 5. Settings中的wifi列表更新wifi信号强度

1. RSSI

  wifi的信号强度使用RSSI表示, 在Android的Framework中会中会转换为对应的格数在状态栏来显示

  RSSI(Received Signal Strength Indication) 代表接收的信号强度指示, 它与模块的发送功率以及天线的增益有关。单位为dBm, 发射端的发出的微波发射后通过空气传播衰减强烈, 在接收端接收到的功率必然会下降, 这时后的接收功率就是RSSI

  信号的绝对功率的表示方式为:

p(dBW) = 10 * lg ( xW / 1W)
p(dBm) = 10 * lg ( x * 1000mW / 1mW)

  可得:

1W = 30dBm = 0dBW
1mW = 0dBm

  因为无线信号多为mW级别(空中传输的过程中衰减较大),所以对它进行了极化,转化为dBm而已,不表示信号是负的。1mW就是0dBm,小于1mW转换为dBm后就为负数

  RSSI的获取 : 在104us内进行基带IQ功率积分得到RSSI的瞬时值,即RSSI(瞬时)=sum(I^2+Q^2);然后在约1秒内对8192个RSSI的瞬时值进行平均得到RSSI的平均值,即RSSI(平均)=sum(RSSI(瞬时))/8192,同时给出1秒内RSSI瞬时值的最大值和RSSI瞬时值大于某一门限时的比率(RSSI瞬时值大于某一门限的个数/8192)。由于 RSSI是通过在数字域进行功率积分而后反推到天线口得到的,反向通道信号传输特性的不一致会影响RSSI的精度

2. 从wpa_supplicant获取RSSI

  1. 对于当前连接的AP, 可以使用wpa_cli的‘signal_poll’命令来获取

    $ wpa_cli -p /data/misc/wifi/sockets/ -i wlan0 signal_poll < RSSI=-60 LINKSPEED=72 NOISE=9999 FREQUENCY=2412
    

    从输出结果中可以看到当前AP的 rssi, linkspeed, frequency

    android framework 在fetchRssiLinkSpeedAndFrequencyNative()中通过WifiNative.signalPoll()来执行wpa_cli的“signal_poll”来获取当前的信号强度

    wifiservice在初始化时, 会调用enableRssiPolling()向WifiStateMachine发送“CMD_ENABLE_RSSI_POLL”来打开 rssi poll, WifiStateMachine在处理该消息时调用fetchRssiLinkSpeedAndFrequencyNative()获取一次当前AP的信号强度,然后发送“CMD_RSSI_POLL”消息, 而WifiStateMachine在处理该消息时调用fetchRssiLinkSpeedAndFrequencyNative()获取一次当前AP的信号强度, 然后再延时3s发送“CMD_RSSI_POLL”消息, 此后, 开始循环获取当前AP的信号强度

  2. 对于未连接的AP, 可以使用wpa_cli的“bss”命令从扫描结果中获取信息

    $ wpa_cli -p /data/misc/wifi/sockets/ -i wlan0 BSS RANGE=0- MASK=0x21987 id=365 bssid=10:c3:7b:d2:df:68 freq=2412 level=-59 tsf=0000270980059560 flags=[WPA2-PSK-CCMP][WPS][ESS] ssid=TDC-647-US
    

    里面的level即代表rssi, 若将“bss”命令的mask置为0x0, 可以获得所有的信息, 但是android framework中只关注其中一部分, 因此设置为0x21987

    android framework 中在每次wpa_supplicant有新的扫描结果时, 通过 WifiNative.scanResults()来执行wpa_cli的“bss”命令, 获取扫描的结果

3. framework层对wifi信号强度的处理

  在frameworks\base\wifi\java\android\net\wifi\WifiInfo.java中定义的无效rssi阈值,以及最大rssi和最小rssi如下

public static final int INVALID_RSSI = -127;
public static final int MIN_RSSI = -126;
public static final int MAX_RSSI = 200;

  在fetchRssiLinkSpeedAndFrequencyNative()中, 通过WifiNative.signalPoll()获取当前AP的信号强度之后, 处理如下

  1. 对于小于INVALID_RSSI和大于MAX_RSSI的值, 都直接修改为INVALID_RSSI,
  2. 对于大于0的RSSI, 减去256, 因为有些厂商的实现为了避免负值, 会将其加上256, 再上报给wpa_supplicant
  3. 调用WifiManager.calculateSignalLevel()计算wifi信号的等级(即wifi信号的格数)
  4. 若wifi信号的等级发生了变化, 则调用sendRssiChangeBroadcast()发送广播(”android.net.wifi.RSSI_CHANGED“)进行通知

  再来看wifi信号等级的计算过程, frameworks\base\wifi\java\android\net\wifi\WifiManager.java中定义了5个wifi信号强度的等级(0格到4格)

 public static final int RSSI_LEVELS = 5;private static final int MIN_RSSI = -100;private static final int MAX_RSSI = -55;public static int calculateSignalLevel(int rssi, int numLevels) {if (rssi <= MIN_RSSI) {return 0;} else if (rssi >= MAX_RSSI) {return numLevels - 1;} else {float inputRange = (MAX_RSSI - MIN_RSSI);float outputRange = (numLevels - 1);return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange);}}
  1. RSSI小于等于-100的为0格
  2. RSSI大于-55的为4格
  3. 按照RSSI分为(-100, -88), [-88, -78), [-78, -67), [-67, -55), [-55, 0) 5 个等级

  再结合wifiinfo中定义的RSSI限值, wifi RSSI的等级划分如下:

  • [-126, -88) 或者 [156, 168) 为 0 格
  • [-88, -78) 或者 [168, 178) 为 1 格
  • [-78, -67) 或者 [178, 189) 为 2 格
  • [-67, -55) 或者 [189, 200) 为 3 格
  • [-55, 0] 或者 为 4 格

  一般 0到-50表示信号最好,-50到-70表示信号偏差,小于-70表示最差,有可能连接不上或者掉线,一般Wifi已断则值为-200

  framework中在为statusbar计算wifi信号格树时, 调用WifiManager.calculateSignalLevel()传递的第二个参数为5(即信号划分为5个等级0~4), 而Settings在调用WifiManager.calculateSignalLevel()传递的第二个参数为4((即信号划分为5个等级0~3))

4. StatusBar 更新wifi信号强度

  WifiStateMachine中在wifi信号等级变化后, 会发送“android.net.wifi.RSSI_CHANGED”并附带当前的rssi值, 而StatusBar中则会接收并处理这一广播

  在StatusBar 的源码 frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java

public NetworkControllerImpl(Context context) {......IntentFilter filter = new IntentFilter();filter.addAction(WifiManager.RSSI_CHANGED_ACTION);......context.registerReceiver(this, filter);......
}public void onReceive(Context context, Intent intent) {......if (action.equals(WifiManager.RSSI_CHANGED_ACTION)|| action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)|| action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {updateWifiState(intent);refreshViews();......
}protected void updateWifiState(Intent intent) {......} else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {mWifiRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);mWifiLevel = WifiManager.calculateSignalLevel(mWifiRssi, WifiIcons.WIFI_LEVEL_COUNT);}updateWifiIcons();
}protected void updateWifiIcons() {int inetCondition = inetConditionForNetwork(ConnectivityManager.TYPE_WIFI);if (mWifiConnected) {mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[inetCondition][mWifiLevel];mQSWifiIconId = WifiIcons.QS_WIFI_SIGNAL_STRENGTH[inetCondition][mWifiLevel];mContentDescriptionWifi = mContext.getString(AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH[mWifiLevel]);} else {......
}

5. Settings中的wifi列表更新wifi信号强度

  首先, 在settings中打开wifi列表时, WifiSettings内部会实例化一个内部类 Scanner

private static class Scanner extends Handler {private int mRetry = 0;private WifiSettings mWifiSettings = null;Scanner(WifiSettings wifiSettings) {mWifiSettings = wifiSettings;}void resume() {if (!hasMessages(0)) {sendEmptyMessage(0);}}void forceScan() {removeMessages(0);sendEmptyMessage(0);}void pause() {mRetry = 0;removeMessages(0);}@Overridepublic void handleMessage(Message message) {if (mWifiSettings.mWifiManager.startScan()) {mRetry = 0;} else if (++mRetry >= 3) {mRetry = 0;Activity activity = mWifiSettings.getActivity();if (activity != null) {Toast.makeText(activity, R.string.wifi_fail_to_scan, Toast.LENGTH_LONG).show();}return;}sendEmptyMessageDelayed(0, WIFI_RESCAN_INTERVAL_MS);}}

  可以看到, Scanner在被触发后, 会间隔WIFI_RESCAN_INTERVAL_MS(一般为10秒)发起一次扫描

  在有扫描结果时, 系统会发出 WifiManager.SCAN_RESULTS_AVAILABLE_ACTION 广播, 而WifiSetting会监听此广播, 并且在WifiSettings.handleEvent()中会调用updateAccessPoints()来更新ui界面

  在wifi打开的情况下, 中会调用updateAccessPoints()会调用constructAccessPoints(), 首先编译所有已经保存的网络,构造对应的AccessPoint, 以ssid作为键, 添加到一个HashMap apMap中去, 然后再遍历所有的扫描结果,添加到apMap中去或者更新apMap中的结果(包括ssid), 最后,带哦用refersh() 更新wifi信号强度的图片

  Settings中wifi列表的信号强度刷新主要依靠 WifiManager.SCAN_RESULTS_AVAILABLE_ACTION 广播来触发, 但是如下广播也会触发信号强度的刷新:

  • WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION
  • WifiManager.LINK_CONFIGURATION_CHANGED_ACTION
  • WifiManager.NETWORK_STATE_CHANGED_ACTION
  • WifiManager.RSSI_CHANGED_ACTION

Android wifi信号强度显示流程相关推荐

  1. Android4.4 状态栏WiFi图标显示流程

    1. 状态栏信号图标 1.1 WIFI信号显示 WIFI信号在状态栏的显示如下图所示 当WiFi状态为关闭时,状态栏不会有任何显示.当WiFi状态打开时,会如上图所示,左侧表示有可用WiFi,右侧表示 ...

  2. android WIFI 信号强度检测

    前几天开会,领导突然说让我们增加个功能,和手机WIFI信号图标一样,会随着信号强度的强弱来改变.(因为我们这里所有状态栏都是隐藏了的,所以这些小东西都得自己写了). 好了,言归正传.我们来说说如何实现 ...

  3. Android WiFi 打开关闭流程

    本文简单介绍下WiFi打开与关闭流程,参考源码Android P. 一.WiFi 开机自动打开流程 系统服务启动的时候会启动WifiService,在SystemService.PHASE_SYSTE ...

  4. Android wifi 信号强度单位 dbm

    当利用android wifi模块获取wifi信号强度值时我们通常会得到-20~-80之间的值,单位是dBm.如:-67dBm. 那么什么是dBm呢? dBm 是表示功率绝对值大小的值,是以1mW功率 ...

  5. Android wifi PNO扫描流程(Andriod O)

    版权声明:本文为博主原创文章,博客地址:https://blog.csdn.net/h784707460/article/details/79702275,未经博主允许不得转载. 一. Android ...

  6. Android APN的显示流程源代码分析

    一.名词介绍 1.PLMN(Public Land Mobile Network,公共陆地移动网络)由政府或它所批准的经营者,为公众提供陆地移动通信业务目的而建立和经营的网络.一句话:一个移动通信网络 ...

  7. android wifi信号强度命令,Android显示wifi信号强度以及周边信号的代码

    本帖最后由 liyihongcug 于 2015-1-19 11:26 编辑 http://blog.sina.com.cn/s/blog_9277d4a30101swxn.htmlhttp://bo ...

  8. Android WIFI认证的流程

    一.背景介绍   当用户打开wifi,扫描完成之后,当用户点击AP列表中一项并输入正确的密码后,就可以开始AP的连接过程了.点击连接到最终连接成功,这个过程中具体流程是如何实现的,这篇文章,将介绍一下 ...

  9. android wifi 图标,android wifi信号强度与图标对应关系

    android中wifi分为5个等级,对应的图标是0格,1格,2格,3格,4格. 那么对应的信号强度是多少呢? 根据wifimanager中的算法calculateSignalLevel可以算得: 0 ...

  10. Android wifi信号强度与图标对应关系

    扫码关注,一起学习 android中wifi分为5个等级,对应的图标是0格,1格,2格,3格,4格. 那么对应的信号强度是多少呢? 根据wifimanager中的算法calculateSignalLe ...

最新文章

  1. python右下角弹出消息
  2. 剑指offer 算法(数组 字符串)
  3. log4j 打印线程号配置_log4j配置参数
  4. Spring IOC 知识点总结,写得太好了!
  5. 字节跳动2021春招启动 提供超7000个岗位
  6. VMware虚拟机安装CentOS6.4、部署web项目全过程(设置固定IP、安装JDK、Tomcat、Redis、部署项目)...
  7. 『华为ICT』数据通信网络基础
  8. linux超出频率限制黑屏,linux suse 超出频率限制 问题
  9. 金融知识图谱有什么?
  10. 递归实现从1加到100
  11. 【Spring Security Oauth2】构建资源服务器(二):授权管理(Web授权,注解授权:securedEnabled, prePostEnabled, jsr250Enabled)
  12. 269. Alien Dictionary火星语字典(拓扑排序)
  13. Map转为String
  14. 计算机冷门知识大全集,阴阳师冷门小知识汇总 冷门小知识合集一览
  15. 校园网登录界面打不开,远程计算机或设备不接受链连接
  16. Safari无痕浏览影响localStorage
  17. python+selenium实现网易邮箱登陆
  18. [RockWell FTPC]随笔_PD更改字体大小
  19. iapp跳转QQ名片代码
  20. LoadLibrary 参数问题

热门文章

  1. JAVA等差素数列蓝桥杯_等差素数列(2017蓝桥杯,二题 )
  2. Jack的E680刷机过程全记录
  3. 超市扫码机器服务器系统搭建,超市用的扫码机是怎么个原理?
  4. 虚拟仿真实验室 服务器,中国美术学院|虚拟仿真实验教学共享平台
  5. 正点原子阿尔法linux开发板USB烧录裸机例程
  6. kali linux 添加字体,在kali linux之下安装wps之后 报错字体缺失
  7. matplotlib绘制鼠标的十字光标(自定义方式,官方实例)
  8. 银联支付接口申请-手机控件支付
  9. 【渝粤教育】广东开放大学 商业银行业务与经营 形成性考核 (32)
  10. Keil4 keil5兼容