Android 8.1 (O)(P)信号强度介绍和定制

本文深入探讨了Android系统中移动数据信号强度的获取与显示机制,详细解析了TelephonyManager类、PhoneStateListener接口的功能,以及信号强度级别映射的具体实现。通过源码分析,揭示了信号强度如何转换为图标显示,特别关注了4G LTE信号的处理过程。
摘要由CSDN通过智能技术生成

0  在Android中对移动数据操作的几个类和接口如下:

1 TelephonyManager 类 主要提供了一系列用于访问与手机通讯相关的状态和信息的get方法。其中包括手机SIM的状态和信息、电信网络的状态及手机用户的信息,在应用程序中可以使用这些get方法获取相关数据

  TelephonyManager类的对象可以通过Context.getSystemService(Context.TELEPHONY_SERVICE)方法来获得,需要注意的是有些通讯信息的获取对应用程序的权限有一定的限制,在开发的时候需要为其添加相应的权限。

2 PhoneStateListener类方法: (移动数据强度和类型 在打电话、SIM卡插拔、连接状态等状态改变而受影响,因此需要在状态下分别检测数据强度和类型 监听回调)

1.onDataActivity(intdirection) :activity 数据状态改变时监听回调

2.onServiceStateChanged(ServiceState serviceState) {//设备服务状态改变监听回调

3.onSignalStrengthsChanged(SignalStrength signalStrength) {//信号强度改变监听回调

4.onDataConnectionStateChanged(intstate) {//数据连接状态

5.onCallStateChanged(intstate, String incomingNumber) {//电话状态改变

 

当信号强度发生变化时,打印log如下

1 SystemUI对于信号强度的客制化
MobileSignalController 对于信号强度的监听:

 class MobilePhoneStateListener extends PhoneStateListener {

        public MobilePhoneStateListener(int subId, Looper looper) {

            super(subId, looper);

        }

 

        @Override

        public void onSignalStrengthsChanged(SignalStrength signalStrength) {

            if (DEBUG) {

                Log.d(mTag, "onSignalStrengthsChanged signalStrength=" + signalStrength +

                        ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));

            }

            mSignalStrength = signalStrength;

            updateTelephony();

        }

.....................................

}


    /**

     * Updates the current state based on mServiceState, mSignalStrength, mDataNetType,

     * mDataState, and mSimState.  It should be called any time one of these is updated.

     * This will call listeners if necessary.

     */

    private final void updateTelephony() {

        if (DEBUG && FeatureOptions.LOG_ENABLE) {

            Log.d(mTag, "updateTelephonySignalStrength: hasService=" + hasService()

                    + " ss=" + mSignalStrength);

        }

        mCurrentState.connected = hasService() && mSignalStrength != null;

        handleIWLANNetwork();

        if (mCurrentState.connected) { //如果有SIM卡信号

                    获取信号强度

            if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) {

                mCurrentState.level = mSignalStrength.getCdmaLevel();

            } else {

                mCurrentState.level = mSignalStrength.getLevel();

            }

            /// M: Customize the signal strength level. @ {

            mCurrentState.level = mStatusBarExt.getCustomizeSignalStrengthLevel(

                    mCurrentState.level, mSignalStrength, mServiceState);

            /// @ }

        }

        if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) {

            mCurrentState.iconGroup = mNetworkToIconLookup.get(mDataNetType);

        } else {

            mCurrentState.iconGroup = mDefaultIcons;

        }

        /// M: Add for data network type.

        mCurrentState.dataNetType = mDataNetType;

        mCurrentState.dataConnected = mCurrentState.connected

                && mDataState == TelephonyManager.DATA_CONNECTED;

        /// M: Add for op network tower type.

        mCurrentState.customizedState = mStatusBarExt.getCustomizeCsState(mServiceState,

                mCurrentState.customizedState);

        /// M: Add for op signal strength tower icon.

        mCurrentState.customizedSignalStrengthIcon = mStatusBarExt.getCustomizeSignalStrengthIcon(

                mSubscriptionInfo.getSubscriptionId(),

                mCurrentState.customizedSignalStrengthIcon,

                mSignalStrength,

                mDataNetType,

                mServiceState);

 

        mCurrentState.roaming = isRoaming();

        if (isCarrierNetworkChangeActive()) {

            mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;

        } else if (isDataDisabled()) {

            mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED;

        }

        if (isEmergencyOnly() != mCurrentState.isEmergency) {

            mCurrentState.isEmergency = isEmergencyOnly();

            mNetworkController.recalculateEmergency();

        }

        // Fill in the network name if we think we have it.

        if (mCurrentState.networkName == mNetworkNameDefault && mServiceState != null

                && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) {

            mCurrentState.networkName = mServiceState.getOperatorAlphaShort();

        }

        /// M: For network type big icon.

        mCurrentState.networkIcon =

            NetworkTypeUtils.getNetworkTypeIcon(mServiceState, mConfig, hasService());

        /// M: For volte type icon.

        mCurrentState.volteIcon = getVolteIcon();

 

        notifyListenersIfNecessary(); //状态栏或下拉状态栏信号格显示

    }

针对于信号强度,经过一系列的调用到

vendor/mediatek/proprietary/frameworks/opt/telephony-base/java/mediatek/telephony/MtkSignalStrength.java


 @Override

    public int getLevel() {

        return super.getLevel();

    }


frameworks/base/telephony/java/android/telephony/SignalStrength.java


    public int getLevel() {

        int level = 0;

        if (isGsm) { //移动或联通卡

            level = getLteLevel(); //首先获取4G信号格

            if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { //未获取到

                level = getTdScdmaLevel(); //获取移动或联通的3G信号格

                if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {//仍然未获取

                    level = getGsmLevel(); //获取移动或联通的2G信号格

                }

            }

        } else {//电信

            int cdmaLevel = getCdmaLevel(); //获取电信2G信号格

            int evdoLevel = getEvdoLevel(); //获取电信3G信号格

            if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {

                /* We don't know evdo, use cdma */

                level = cdmaLevel;

            } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {

                /* We don't know cdma, use evdo */

                level = evdoLevel;

            } else {

                /* We know both, use the lowest level */

                level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;

            }

        }

        if (DBG) log("getLevel=" + level);

        return level;

    }

在此介绍下手机是几模的配置:GSM是移动和联通公用的band;LTE从编码方式上分为TDD和FDD,从频段上分有各种不同的band

移动:GSM、TDSCDMA、LTE(TDD)

联通:GSM、WCDMA、LTE(FDD)

电信:CDMA、EVDO、LTE(FDD)

因此如果手机支持GSM、WCDMA、TDSCDMA、TDD-LTE、FDD-LTE 这是五模;加上 CDMA、EVDO 就是七模

对于移动和联通,是先获取4G信号;在MtkSignalStrength中:


    /**

     * Get LTE as level 0..4

     *

     * @hide

     */

    @Override

    public int getLteLevel() {

        int rsrpIconLevel = -1;

        ISignalStrengthExt ssExt = getOpInstance(); //获取ISignalStrengthExt实例

        if (ssExt != null) {

            rsrpIconLevel = ssExt.mapLteSignalLevel(mLteRsrp, mLteRssnr, mLteSignalStrength);

            return rsrpIconLevel;

        } else {

            log("[getLteLevel] null op customization instance");

        }

 

        return super.getLteLevel(); //如果上述获取不到信号格。则调用父类SignalStrength的getLteLevel方法

    }
 

vendor/mediatek/proprietary/frameworks/opt/telephony-base/java/mediatek/telephony/SignalStrengthExt.java


    public int mapLteSignalLevel(int mLteRsrp, int mLteRssnr, int mLteSignalStrength) {

        /*

         * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received

         * signal + noise RSRP = reference signal dBm RSRQ = quality of signal

         * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio

         * = -10log P1/P2 dB

         */

        int rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;

        int rsrpIconLevel = -1;

        int snrIconLevel = -1;

 

        if (mLteRsrp > -44) {

            rsrpIconLevel = -1;

        } else if (mLteRsrp >= -85) {

            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_GREAT; //4格

        } else if (mLteRsrp >= -95) {

            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_GOOD; //3格

        } else if (mLteRsrp >= -105) {

            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_MODERATE; //2格

        } else if (mLteRsrp >= -115) {

            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_POOR;  //1格

        } else if (mLteRsrp >= -140) { //0格

            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;

        }

 

        /*

         * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5

         * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars

         * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna

         * Icon Only

         */

        if (mLteRssnr > 300) {

            snrIconLevel = -1;

        } else if (mLteRssnr >= 130) {

            snrIconLevel = SignalStrength.SIGNAL_STRENGTH_GREAT;

        } else if (mLteRssnr >= 45) {

            snrIconLevel = SignalStrength.SIGNAL_STRENGTH_GOOD;

        } else if (mLteRssnr >= 10) {

            snrIconLevel = SignalStrength.SIGNAL_STRENGTH_MODERATE;

        } else if (mLteRssnr >= -30) {

            snrIconLevel = SignalStrength.SIGNAL_STRENGTH_POOR;

        } else if (mLteRssnr >= -200) {

            snrIconLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;

        }

        Rlog.i(TAG, "getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"

                + rsrpIconLevel + " snrIconLevel:" + snrIconLevel);

 

        /* Choose a measurement type to use for notification */

        if (snrIconLevel != -1 && rsrpIconLevel != -1) {

            /*

             * The number of bars displayed shall be the smaller of the bars

             * associated with LTE RSRP and the bars associated with the LTE

             * RS_SNR

             */

            return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);

        }

 

        if (snrIconLevel != -1) {

            return snrIconLevel;

        }

 

        if (rsrpIconLevel != -1) {

            return rsrpIconLevel;

        }

 

        /* Valid values are (0-63, 99) as defined in TS 36.331 */

        if (mLteSignalStrength > 63) {

            rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;

        } else if (mLteSignalStrength >= 12) {

            rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_GREAT;

        } else if (mLteSignalStrength >= 8) {

            rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_GOOD;

        } else if (mLteSignalStrength >= 5) {

            rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_MODERATE;

        } else if (mLteSignalStrength >= 0) {

            rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_POOR;

        }

        Rlog.i(TAG, "getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"

                + rssiIconLevel);

        return rssiIconLevel;

    }

因此如果想修改强度对应的信号格显示,请修改上述对应强度值;对于上述变量的介绍请参考博客关于LTE RSRP、RSSI、SINR、RSRQ定义

2 状态栏或下拉状态栏信号格显示

MobileSignalController


  public void notifyListenersIfNecessary() {

        if (isDirty()) {

            saveLastState();

            notifyListeners();

        }

    }

    public final void notifyListeners() {

        notifyListeners(mCallbackHandler);

    }
因此调用到SignalClusterView


 @Override

    public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,

             int networkType, int volteIcon, int qsType, boolean activityIn, boolean activityOut,

             String typeContentDescription, String description, boolean isWide, int subId,

              boolean roaming) {

        PhoneState state = getState(subId);

        if (state == null) {

            return;

        }

        state.mMobileVisible = statusIcon.visible && !mBlockMobile;

        state.mMobileStrengthId = statusIcon.icon;

        state.mMobileTypeId = statusType;

        state.mMobileDescription = statusIcon.contentDescription;

        state.mMobileTypeDescription = typeContentDescription;

        state.mIsMobileTypeIconWide = statusType != 0 && isWide;

        /// M: for big network icon and volte icon.

        state.mNetworkIcon = networkType;

        state.mVolteIcon = volteIcon;

        state.mRoaming = roaming;

        state.mActivityIn = activityIn && mActivityEnabled;

        state.mActivityOut = activityOut && mActivityEnabled;

 

        /// M: Add for plugin features. @ {

        state.mDataActivityIn = activityIn;

        state.mDataActivityOut = activityOut;

        /// @ }

 

        apply();

    }
 


        public boolean apply(boolean isSecondaryIcon) { //信号格显示到状态栏

            if (mMobileVisible && !mIsAirplaneMode) {

                if (mLastMobileStrengthId != mMobileStrengthId) {

                    mMobile.getDrawable().setLevel(mMobileStrengthId);

                    mMobileDark.getDrawable().setLevel(mMobileStrengthId);

                    mLastMobileStrengthId = mMobileStrengthId;

                }

 

                if (mLastMobileTypeId != mMobileTypeId) {

                    if (!mPhoneStateExt.disableHostFunction()) {

                        mMobileType.setImageResource(mMobileTypeId);

                    }

                    mLastMobileTypeId = mMobileTypeId;

                }

 

                mMobileGroup.setContentDescription(mMobileTypeDescription

                        + " " + mMobileDescription);

                mMobileGroup.setVisibility(View.VISIBLE);

                showViewInWfcCase();

            } else {

                if (mIsAirplaneMode && (mIsWfcEnable && mVolteIcon != 0)) {

                    /// M:Bug fix for show vowifi icon in flight mode

                    mMobileGroup.setVisibility(View.VISIBLE);

                    hideViewInWfcCase();

                } else {

                    if (DEBUG) {

                        Log.d(TAG, "setVisibility as GONE, this = " + this

                                + ", mMobileVisible = " + mMobileVisible

                                + ", mIsAirplaneMode = " + mIsAirplaneMode

                                + ", mIsWfcEnable = " + mIsWfcEnable

                                + ", mVolteIcon = " + mVolteIcon);

                    }

                    mMobileGroup.setVisibility(View.GONE);

                }

            }

 ..............................................

 

            return mMobileVisible;

        }
 

 

 

 

 

 

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值