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卡运营商信息的读取和显示流程

Android系统分析之运营商显示流程分析之运营商信息的获取和赋值一

上一篇:手机/P各种提示框整合,纯js实现,比前端大多数框架的提示消息更好用


下一篇:Android系统分析之运营商显示流程分析之运营商信息的读取流程二