Android系統分析之運營商顯示流程分析之運營商信息的獲取和賦值一


運營商顯示流程分析之運營商信息的獲取和賦值

一. SIM卡運營商和網絡運營商

SIM卡運營商即SPN, 網絡運營商即PLMN, 首先我們需要知道SIM卡運營商和網絡運營商的獲取方式, 如下:

private TelephonyManager mTelephonyManager;
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

// 獲取SIM卡運營商名稱及SIM卡運營商代碼(MCCMNC碼)
String simOperator = mTelephonyManager.getSimOperator();
String networkOperator = mTelephonyManager.getNetworkOperator();

// 獲取網絡運營商名稱及網絡運營商代碼(MCCMNC碼)
String simOperatorName = mTelephonyManager.getSimOperatorName();
String networkOperatorName = mTelephonyManager.getNetworkOperatorName();

二. 獲取SIM卡和網絡運營商信息的具體實現

我們通過TelephonyManager獲取的SIM卡和網絡運營商的相關信息, 因此首先我們到TelephonyManager中查看實現方式:

/**
 * Returns the MCC+MNC (mobile country code + mobile network code) of the
 * provider of the SIM. 5 or 6 decimal digits.
 * <p>
 * Availability: SIM state must be {@link #SIM_STATE_READY}
 *
 * @see #getSimState
 */
public String getSimOperator() {
    return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC);
}

/**
 * Returns the Service Provider Name (SPN).
 * <p>
 * Availability: SIM state must be {@link #SIM_STATE_READY}
 *
 * @see #getSimState
 */
public String getSimOperatorName() {
    return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA);
}

/**
 * Returns the alphabetic name of current registered operator.
 * <p>
 * Availability: Only when user is registered to a network. Result may be
 * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
 * on a CDMA network).
 */
public String getNetworkOperatorName() {
    return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ALPHA);
}

/**
 * Returns the numeric name (MCC+MNC) of current registered operator.
 * <p>
 * Availability: Only when user is registered to a network. Result may be
 * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
 * on a CDMA network).
 */
public String getNetworkOperator() {
    return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
}

通過上面的TelephonyManager的源碼我們可以發現, SIM卡和網絡運營商的信息是通過獲取系統的屬性得到的, 因此我們只需要查詢到上面的屬性是在何處被賦值的, 就可以知道該信息的來源

需要查詢的屬性如下:

TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC,
TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA,
TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
TelephonyProperties.PROPERTY_OPERATOR_NUMERIC

通過全局搜索, 可以發現TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERICTelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA是在SIMRecords中被賦值的

/**
 * Finite State Machine to load Service Provider Name , which can be stored
 * in either EF_SPN (3GPP), EF_SPN_CPHS, or EF_SPN_SHORT_CPHS (CPHS4.2)
 *
 * After starting, FSM will search SPN EFs in order and stop after finding
 * the first valid SPN
 *
 * If the FSM gets restart while waiting for one of
 * SPN EFs results (i.e. a SIM refresh occurs after issuing
 * read EF_CPHS_SPN), it will re-initialize only after
 * receiving and discarding the unfinished SPN EF result.
 *
 * @param start set true only for initialize loading
 * @param ar the AsyncResult from loadEFTransparent
 *        ar.exception holds exception in error
 *        ar.result is byte[] for data in success
 */
private void getSpnFsm(boolean start, AsyncResult ar) {
	...
    switch(mSpnState){ 
		...
        case READ_SPN_3GPP:
            if (ar != null && ar.exception == null) {
                data = (byte[]) ar.result;
                mSpnDisplayCondition = 0xff & data[0];
                mSpn = IccUtils.adnStringFieldToString(data, 1, data.length - 1);
                ...
                // 設置SIM卡運營商名稱
                SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, mSpn);
                mSpnState = GetSpnFsmState.IDLE;
            } else {
                ...
            }
            break;
        case READ_SPN_CPHS:
            if (ar != null && ar.exception == null) {
                data = (byte[]) ar.result;
                mSpn = IccUtils.adnStringFieldToString(data, 0, data.length);
				...
				// 設置SIM卡運營商名稱
                SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, mSpn);
                mSpnState = GetSpnFsmState.IDLE;
            } else {
                ...
            }
            break;
        case READ_SPN_SHORT_CPHS:
            if (ar != null && ar.exception == null) {
                data = (byte[]) ar.result;
                mSpn = IccUtils.adnStringFieldToString(data, 0, data.length);
                ...
				// 設置SIM卡運營商名稱
                SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, mSpn);
            }else {
                ...
            }

        ...
    }
}

@Override
protected void onAllRecordsLoaded() {
    ...
    String operator = getOperatorNumeric();
    if (!TextUtils.isEmpty(operator)) {
        ...
		// 設置運營商代碼
        SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator);
    } else {
        log("onAllRecordsLoaded empty 'gsm.sim.operator.numeric' skipping");
    }
    ...
}

TelephonyProperties.PROPERTY_OPERATOR_ALPHATelephonyProperties.PROPERTY_OPERATOR_NUMERIC是在GsmServiceStateTracker中賦值的

private void pollStateDone() {
    ...
	if (hasChanged) {
       String operatorNumeric;

       updateSpnDisplay();
       // 設置網絡運營商名稱
       mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
           mSS.getOperatorAlphaLong());

       String prevOperatorNumeric =
               SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
       operatorNumeric = mSS.getOperatorNumeric();
	   // 設置網絡運營商代碼
       mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
	   // 更新配置
       updateCarrierMccMncConfiguration(operatorNumeric,
               prevOperatorNumeric, mPhone.getContext());
        ...
        // 是否是漫游
        mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
            mSS.getRoaming() ? "true" : "false");

        mPhone.notifyServiceStateChanged(mSS);
    }
    ...
}  

通過上面的步驟, 我們已經知道SIM卡和運營商信息的獲取及是在何處被賦值, 接下來分析SIM卡運營商信息的讀取和顯示流程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM