Android 8.1 (O)(P)信號強度介紹和定製

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;

        }
 

 

 

 

 

 

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章