首页 > 其他分享 >安卓显示WiFi信号强度流程

安卓显示WiFi信号强度流程

时间:2024-03-12 19:34:03浏览次数:14  
标签:return calculateSignalLevel int 安卓 WiFi 信号强度 RSSI

文章目录

1 概要

本文主要讲述了安卓导航栏里WiFi信号的获取流程

安卓版本:各版本通用

2 整体架构流程

2.1 安卓10及其以下

a)跟WiFi UI强相关的内容,一般可以到如下目录中去寻找:packages/apps/Settings/src/com/android/settings/wifi/

b)在packages/apps/Settings/src/com/android/settings/wifi/details/下有一个WifiDetailPreferenceController.java 类,该类中会对WiFi的信息进行配置。

c)在WifiDetailPreferenceController中,首先可以看到其注册了一个BroadcastReceiver,主要接收的广播有:CONFIGURED_NETWORKS_CHANGED_ACTION、

NETWORK_STATE_CHANGED_ACTION、RSSI_CHANGED_ACTION,这里我们只关心RSSI_CHANGED_ACTION这个广播,在接受广播之后是调用了refreshPage()方法。

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION:
                    if (!intent.getBooleanExtra(WifiManager.EXTRA_MULTIPLE_NETWORKS_CHANGED,
                            false /* defaultValue */)) {
                        // only one network changed
                        WifiConfiguration wifiConfiguration = intent
                                .getParcelableExtra(WifiManager.EXTRA_WIFI_CONFIGURATION);
                        if (mAccessPoint.matches(wifiConfiguration)) {
                            mWifiConfig = wifiConfiguration;
                        }
                    }
                    // fall through
                case WifiManager.NETWORK_STATE_CHANGED_ACTION:
                case WifiManager.RSSI_CHANGED_ACTION:
                    refreshPage();
                    break;
            }
        }
    };

d)在refreshPage()方法中,首先会通过updateAccessPoint()来判断AP的信息是否有更新,有更新的话其次则会refresh各类信息,这里我们只关心refreshRssiViews()。

    private void refreshPage() {
        if(!updateAccessPoint()) {
            return;
        }

        Log.d(TAG, "Update UI!");

        // refresh header
        refreshEntityHeader();

        // refresh Buttons
        refreshButtons();

        // Update Connection Header icon and Signal Strength Preference
        refreshRssiViews();
        // Frequency Pref
        refreshFrequency();
        // Transmit Link Speed Pref
        refreshTxSpeed();
        // Receive Link Speed Pref
        refreshRxSpeed();
        // IP related information
        refreshIpLayerInfo();
        // SSID Pref
        refreshSsid();
        // MAC Address Pref
        refreshMacAddress();
    }

e)在refreshRssiViews()方法中,首先就会调用mAccessPoint.getLevel()来获取当前信号强度信息;其次则会判断RSSI是否在指定范围,如果不在指定范围则将其控件不显示,并且将信号强度设置为-1;最后则是通过mIconInjector.getIcon(mRssiSignalLevel)和mSignalStrengthPref.setIcon(wifiIconDark)来设置界面的WiFi信号强度。

    private void refreshRssiViews() {
        int signalLevel = mAccessPoint.getLevel();

        // Disappears signal view if not in range. e.g. for saved networks.
        if (mIsOutOfRange) {
            mSignalStrengthPref.setVisible(false);
            mRssiSignalLevel = -1;
            return;
        }

        if (mRssiSignalLevel == signalLevel) {
            return;
        }
        mRssiSignalLevel = signalLevel;
        Drawable wifiIcon = mIconInjector.getIcon(mRssiSignalLevel);

        if (mEntityHeaderController != null) {
            mEntityHeaderController
                    .setIcon(redrawIconForHeader(wifiIcon)).done(mFragment.getActivity(),
                            true /* rebind */);
        }

        Drawable wifiIconDark = wifiIcon.getConstantState().newDrawable().mutate();
        wifiIconDark.setTintList(Utils.getColorAttr(mContext, android.R.attr.colorControlNormal));
        mSignalStrengthPref.setIcon(wifiIconDark);

        mSignalStrengthPref.setSummary(mSignalStr[mRssiSignalLevel]);
        mSignalStrengthPref.setVisible(true);
    }

f)在AccessPoint.getLevel()方法中,会调用WifiManager.calculateSignalLevel(mRssi, SIGNAL_LEVELS)来获取到RSSI以及信号强度。

PS:AccessPoint类中都是一些WiFi的信息,例如BSSID、SSID、安全类型、RSSI等。

    /**
     * Returns the number of levels to show for a Wifi icon, from 0 to {@link #SIGNAL_LEVELS}-1.
     *
     * <p>Use {@#isReachable()} to determine if an AccessPoint is in range, as this method will
     * always return at least 0.
     */
    public int getLevel() {
        return WifiManager.calculateSignalLevel(mRssi, SIGNAL_LEVELS);
    }

g)在WifiManager.calculateSignalLevel()方法中,会通过传进来的RSSI进行信号强度的计算。首先会判断当前的Rssi是否小于最小的Rssi,并且大于最大的Rssi(MIN_RSSI=-100、MAX_RSSI=-55);其次如果当前Rssi符合要求的话,则会对WiFi信号强度进行计算,最后会对计算出的结果进行取整,并返回到UI界面中。

例:如果当前的Rssi为-60,则计算来的WiFi信号强度为:(-60+100)* 4 / (-55+100)= 3.55555556 ,最后对结果进行向下取整,最后输出的WiFi信号强度等级为3。

    /**
     * Calculates the level of the signal. This should be used any time a signal
     * is being shown.
     *
     * @param rssi The power of the signal measured in RSSI.
     * @param numLevels The number of levels to consider in the calculated
     *            level.
     * @return A level of the signal, given in the range of 0 to numLevels-1
     *         (both inclusive).
     */
    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);
        }
    }

如上就是大致的获取WiFi信号强度的流程 ,但是这只适用于安卓10以及安卓10以下的版本,安卓11及其以上,在WifiManager.calculateSignalLevel()的使用上会有些许差别。

2.2 安卓11及其以上

a)安卓10和安卓11的差别在于AccessPoint.getLevel()方法,可以看到安卓10传进了两个参数,而安卓11只传进了一个参数。

安卓10:WifiManager.calculateSignalLevel(mRssi, SIGNAL_LEVELS)

安卓11:getWifiManager().calculateSignalLevel(mRssi)

b)其次在WifiManager中可以看到,  calculateSignalLevel(int rssi, int numLevels)是被废弃的接口,而真正被使用的是calculateSignalLevel(int rssi)这个接口。在calculateSignalLevel()方法中则会调用WifiServiceImpl的calculateSignalLevel()方法。

c)在WifiServiceImpl.calculateSignalLevel()方法中,会调用RssiUtil.calculateSignalLevel()。

    @Override
    public int calculateSignalLevel(int rssi) {
        return RssiUtil.calculateSignalLevel(mContext, rssi);
    }

d)在RssiUtil.calculateSignalLevel()方法中首先会通过getRssiLevelThresholds()来获取到rssi对应的信号强度;其次通过循环计算出当前的信号强度为多少。

数组thresholds的具体数值如下:

    <integer-array translatable="false" name="config_wifiRssiLevelThresholds">
                         <!-- RSSI                RSSI Level -->
        <item>-88</item> <!-- (-infinity, -88)             0 -->
        <item>-77</item> <!-- [-88, -77)                   1 -->
        <item>-66</item> <!-- [-77, -66)                   2 -->
        <item>-55</item> <!-- [-66, -55)                   3 -->
                         <!-- [-55, +infinity)             4 -->
    </integer-array>

例:如果当前的Rssi为-60,首先会对比thresholds[0],-60>-88;继续进行对比thresholds[1],-60>-77;继续进行对比thresholds[2],-60>-66;继续进行对比thresholds[3]。-60<-55,所以当前RSSI对应的信号强度为:3。

    /** Calculate RSSI level from RSSI using overlaid RSSI level thresholds. */
    public static int calculateSignalLevel(Context context, int rssi) {
        int[] thresholds = getRssiLevelThresholds(context);

        for (int level = 0; level < thresholds.length; level++) {
            if (rssi < thresholds[level]) {
                return level;
            }
        }
        return thresholds.length;
    }

    @NonNull
    private static int[] getRssiLevelThresholds(Context context) {
        // getIntArray() will never return null, it will throw instead
        return context.getResources().getIntArray(R.array.config_wifiRssiLevelThresholds);
    }

3 小结

 RSSI对应的信号强度差不多就是通过如上流程来获取的,如果要是客户有一些定制化的需求,例如要修改RSSI的阈值:

a)安卓10及其以下则可以通过修改WifiManager.calculateSignalLevel()中计算RSSI对应信号强度的逻辑来达到目的。(rssi在某个范围内就返回多少的信号强度)

b)在安卓11及其以上则可以通过修改packages/modules/Wifi/service/ServiceWifiResources/res/values/config.xml中config_wifiRssiLevelThresholds的<item>值来达到目的。

标签:return,calculateSignalLevel,int,安卓,WiFi,信号强度,RSSI
From: https://blog.csdn.net/weixin_45316524/article/details/136596119

相关文章

  • 海信安卓电视安装影视APP-新增直播和点播
    灵活掌握本文的相关知识点后可以给任何安卓设备(硬件支持情况下)添加直播和点播功能海信安卓电视安装影视APP-安装方法步骤直播:DIYP影音经典版.apk点播:蜂蜜2.1.6正式版tv电视.apk朗读全文Yourbrowserdoesnotsupporttheaudioelement.#步骤开启安卓......
  • 如何建立dns隧道来突破连接WIFI后用户密码认证的上网方式
    2024.3.5优化了DNS的A记录(经测试优化t1ns的A记录成功)朗读全文Yourbrowserdoesnotsupporttheaudioelement.有什么用建立dns隧道来突破连接WIFI后用户密码认证的上网方式学习和了解iodine的工作原理实测环境:J4125中的OpenWrt;作为服务端MacOSX电脑;作为客户......
  • 基于WiFi的防盗报警Python脚本
    学校图书馆有一本电子书,可以供学生阅读,但是怎么防止学生将其带出图书馆呢?我把它连上馆内的一台电脑的WiFi热点,间隔一段时间就从电脑ping这台电子书,如果ping不通,说明电子书脱离了WiFi信号范围,电脑就会响起报警声。代码思路如下,先通过Windows上的arp命令,用设备的MAC地址获取其IP,再......
  • 安卓)提升大脑算力 棋牌类
    棋路象棋,官网版本:https://www.mdevs.cn/安卓安装包125.2MB,版本2.6.3,实测可选免登录/微信登录可同步棋谱练习提示次数免费10次,之后需要看广告或支持作者免广告吾爱版本的安卓安装包47.6MB,版本1.5.1https://qoop.lanzouj.com/i1FAVelhewd该版本有悔棋按钮和提示(在悔棋后面......
  • ESP32CAM使用Quirc识别二维码并连接WIFI
    ESP32CAM使用Quirc识别二维码并连接WIFI网上有教程,但是是要做出来很难,或者说做出来报错识别不了。前提:搭建好ESP-IDF环境CAMERA能成功初始化此处用的二维码识别库是用的quirc,如下这个和Github下载的差不多,加了个CMakeList,我会把这个传到我的Github上,感兴趣去下载Lesterbor/E......
  • WIFI&蓝牙(ESP32)转CAN总线&串口TTL模块-C1-设备作为Modbus Slave实现RS485 Modbus RT
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ESP32_CAN"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p> 说明这节测试的是让设备作为Modbus......
  • 安卓开发学习-按钮控件
    java代码点击查看代码packagecom.android.myapp;importandroid.annotation.SuppressLint;importandroid.os.Bundle;importandroid.widget.CheckBox;importandroid.widget.RadioGroup;importandroid.widget.Switch;importandroid.widget.TextView;importandroi......
  • 安卓开发学习-向上一个Activity返回数据
    发送请求页面点击查看代码packagecom.android.response;importandroid.content.Intent;importandroid.os.Bundle;importandroid.widget.Button;importandroid.widget.TextView;importandroidx.activity.result.ActivityResultLauncher;importandroidx.activity.......
  • 安卓开发学习-Intent携带数据
    发送数据页面点击查看代码packagecom.android.messaging;importandroid.annotation.SuppressLint;importandroid.content.Intent;importandroid.os.Bundle;importandroid.widget.Button;importandroid.widget.TextView;importandroidx.appcompat.app.AppCompatA......
  • Delphi11安装Android安卓SDK
    由于Google的AndroidSDK不再允许其他程序分发。Delphi11安装后,默认是没有Android安卓SDK的,在默认安装路径的情况下,在C:\Users\Public\Documents\Embarcadero\Studio\22.0\CatalogRepository\AndroidSDK-2525-22.0.46141.0937\目录下面,只有最基本的安卓SDK的命令行工具,我们可以使......