Android wifi信号强度显示流程
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
对于当前连接的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的信号强度
对于未连接的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的信号强度之后, 处理如下
- 对于小于INVALID_RSSI和大于MAX_RSSI的值, 都直接修改为INVALID_RSSI,
- 对于大于0的RSSI, 减去256, 因为有些厂商的实现为了避免负值, 会将其加上256, 再上报给wpa_supplicant
- 调用WifiManager.calculateSignalLevel()计算wifi信号的等级(即wifi信号的格数)
- 若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);}}
- RSSI小于等于-100的为0格
- RSSI大于-55的为4格
- 按照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信号强度显示流程相关推荐
- Android4.4 状态栏WiFi图标显示流程
1. 状态栏信号图标 1.1 WIFI信号显示 WIFI信号在状态栏的显示如下图所示 当WiFi状态为关闭时,状态栏不会有任何显示.当WiFi状态打开时,会如上图所示,左侧表示有可用WiFi,右侧表示 ...
- android WIFI 信号强度检测
前几天开会,领导突然说让我们增加个功能,和手机WIFI信号图标一样,会随着信号强度的强弱来改变.(因为我们这里所有状态栏都是隐藏了的,所以这些小东西都得自己写了). 好了,言归正传.我们来说说如何实现 ...
- Android WiFi 打开关闭流程
本文简单介绍下WiFi打开与关闭流程,参考源码Android P. 一.WiFi 开机自动打开流程 系统服务启动的时候会启动WifiService,在SystemService.PHASE_SYSTE ...
- Android wifi 信号强度单位 dbm
当利用android wifi模块获取wifi信号强度值时我们通常会得到-20~-80之间的值,单位是dBm.如:-67dBm. 那么什么是dBm呢? dBm 是表示功率绝对值大小的值,是以1mW功率 ...
- Android wifi PNO扫描流程(Andriod O)
版权声明:本文为博主原创文章,博客地址:https://blog.csdn.net/h784707460/article/details/79702275,未经博主允许不得转载. 一. Android ...
- Android APN的显示流程源代码分析
一.名词介绍 1.PLMN(Public Land Mobile Network,公共陆地移动网络)由政府或它所批准的经营者,为公众提供陆地移动通信业务目的而建立和经营的网络.一句话:一个移动通信网络 ...
- android wifi信号强度命令,Android显示wifi信号强度以及周边信号的代码
本帖最后由 liyihongcug 于 2015-1-19 11:26 编辑 http://blog.sina.com.cn/s/blog_9277d4a30101swxn.htmlhttp://bo ...
- Android WIFI认证的流程
一.背景介绍 当用户打开wifi,扫描完成之后,当用户点击AP列表中一项并输入正确的密码后,就可以开始AP的连接过程了.点击连接到最终连接成功,这个过程中具体流程是如何实现的,这篇文章,将介绍一下 ...
- android wifi 图标,android wifi信号强度与图标对应关系
android中wifi分为5个等级,对应的图标是0格,1格,2格,3格,4格. 那么对应的信号强度是多少呢? 根据wifimanager中的算法calculateSignalLevel可以算得: 0 ...
- Android wifi信号强度与图标对应关系
扫码关注,一起学习 android中wifi分为5个等级,对应的图标是0格,1格,2格,3格,4格. 那么对应的信号强度是多少呢? 根据wifimanager中的算法calculateSignalLe ...
最新文章
- python右下角弹出消息
- 剑指offer 算法(数组 字符串)
- log4j 打印线程号配置_log4j配置参数
- Spring IOC 知识点总结,写得太好了!
- 字节跳动2021春招启动 提供超7000个岗位
- VMware虚拟机安装CentOS6.4、部署web项目全过程(设置固定IP、安装JDK、Tomcat、Redis、部署项目)...
- 『华为ICT』数据通信网络基础
- linux超出频率限制黑屏,linux suse 超出频率限制 问题
- 金融知识图谱有什么?
- 递归实现从1加到100
- 【Spring Security Oauth2】构建资源服务器(二):授权管理(Web授权,注解授权:securedEnabled, prePostEnabled, jsr250Enabled)
- 269. Alien Dictionary火星语字典(拓扑排序)
- Map转为String
- 计算机冷门知识大全集,阴阳师冷门小知识汇总 冷门小知识合集一览
- 校园网登录界面打不开,远程计算机或设备不接受链连接
- Safari无痕浏览影响localStorage
- python+selenium实现网易邮箱登陆
- [RockWell FTPC]随笔_PD更改字体大小
- iapp跳转QQ名片代码
- LoadLibrary 参数问题
热门文章
- JAVA等差素数列蓝桥杯_等差素数列(2017蓝桥杯,二题 )
- Jack的E680刷机过程全记录
- 超市扫码机器服务器系统搭建,超市用的扫码机是怎么个原理?
- 虚拟仿真实验室 服务器,中国美术学院|虚拟仿真实验教学共享平台
- 正点原子阿尔法linux开发板USB烧录裸机例程
- kali linux 添加字体,在kali linux之下安装wps之后 报错字体缺失
- matplotlib绘制鼠标的十字光标(自定义方式,官方实例)
- 银联支付接口申请-手机控件支付
- 【渝粤教育】广东开放大学 商业银行业务与经营 形成性考核 (32)
- Keil4 keil5兼容