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

  • 相关阅读:
    动态模板列更新数据分页的例子
    Oracle SCN机制解析
    阻止特定的ip登陆数据库的2种方法 (轉)
    Oracle动态执行SQL四种方式的例子
    使用Oracle的DBMS_SQL包执行动态SQL语句
    Oracle XML DB之浅入浅出
    将oracle设为归档模式和非归档模式启动的方法
    如何修改Oracle數據庫字符集
    (原創)C#使用QueryTables導出到Excel
    常用SQL語句2
  • 原文地址:https://www.cnblogs.com/firmly-believe/p/10764381.html
Copyright © 2020-2023  润新知