Android中的mcc和mnc

mcc和mnc概述

mcc和mnc见 MCC(移动国家码)和 MNC(移动网络码)

MCC:Mobile Country Code,移动国家码,MCC的资源由国际电联(ITU)统一分配和管理,唯一识别移动用户所属的国家,共3位,中国为460;  

MNC:Mobile Network Code,移动网络码,共2位,中国移动TD系统使用00,中国联通GSM系统使用01,中国移动GSM系统使用02,中国电信CDMA系统使用03

MccTable

Android中相关的代码在telephony framwork中,主要是frameworks/opt/telephony/src/java/com/android/internal/telephony/MccTable.java。

static {
        sTable = new ArrayList<MccEntry>(240);


        /*
         * The table below is built from two resources:
         *
         * 1) ITU "Mobile Network Code (MNC) for the international
         *   identification plan for mobile terminals and mobile users"
         *   which is available as an annex to the ITU operational bulletin
         *   available here: http://www.itu.int/itu-t/bulletin/annex.html
         *
         * 2) The ISO 3166 country codes list, available here:
         *    http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
         *
         * This table has not been verified.
         */

		sTable.add(new MccEntry(202,"gr",2));	//Greece
		sTable.add(new MccEntry(204,"nl",2));	//Netherlands (Kingdom of the)
                ...
		sTable.add(new MccEntry(460,"cn",2));	//China (People's Republic of)
		sTable.add(new MccEntry(461,"cn",2));	//China (People's Republic of)
                ...
		sTable.add(new MccEntry(748,"uy",2));	//Uruguay (Eastern Republic of)
		sTable.add(new MccEntry(750,"fk",2));	//Falkland Islands (Malvinas)
        //table.add(new MccEntry(901,"",2));	//"International Mobile, shared code"

        Collections.sort(sTable);
    }
该类静态块初始化了一个列表sTable,列表的每一项目是MccEntry。

static class MccEntry implements Comparable<MccEntry> {
        final int mMcc;
        final String mIso;
        final int mSmallestDigitsMnc;
        ...
        @Override
        public int compareTo(MccEntry o) {
            return mMcc - o.mMcc;
        }
}
MccEntry的每一项包换了mcc,iso,和该国最小的mnc。类中实现了比较方法,这样初始化中排序实际就是按照mcc排序由小到大。

MccTable类中的其余方法基本是使用sTable,例如:

    public static String countryCodeForMcc(int mcc) {
        MccEntry entry = entryForMcc(mcc);

        if (entry == null) {
            return "";
        } else {
            return entry.mIso;
        }
    }

MccTable的使用

frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java

protected void fixTimeZone() {
     ...
     mcc = operatorNumeric.substring(0, 3);
     ...
     iso = MccTable.countryCodeForMcc(Integer.parseInt(mcc));
     ...
     zone = getTimeZonesWithCapitalCity(iso);
     ...
     saveNitzTimeZone(zone.getID());
     ...
}
例如修改时区的时候依据mcc确定iso,依据iso最终确定时区。

MCC和MNC更新流程和对系统的影响

frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
private void pollStateDone() {
     ...
     updateCarrierMccMncConfiguration(operatorNumeric,
             prevOperatorNumeric, mPhone.getContext());
     ...
}
pollStateDone被调用的流程可参见 点击打开链接,然后运行基类的updateCarrierMccMncConfiguration
   protected void updateCarrierMccMncConfiguration(String newOp, String oldOp, Context context) {
        if (((newOp == null) && (TextUtils.isEmpty(oldOp) == false)) ||
                ((newOp != null) && (newOp.equals(oldOp) == false))) {
            MccTable.updateMccMncConfiguration(context, newOp, true);
        }
    }
跳转到之前提到的MccTable类中:
public static void updateMccMncConfiguration(Context context, String mccmnc,
            boolean fromServiceState) {     

        if (!TextUtils.isEmpty(mccmnc)) {
            int mcc, mnc;

            String defaultMccMnc = TelephonyManager.getDefault().getSimOperatorNumeric();

            try {
                mcc = Integer.parseInt(mccmnc.substring(0,3));
                mnc = Integer.parseInt(mccmnc.substring(3));
            } catch (NumberFormatException e) {
                Slog.e(LOG_TAG, "Error parsing IMSI: " + mccmnc);
                return;
            }
        
            if (mcc != 0) {
                setTimezoneFromMccIfNeeded(context, mcc);
            }
            if (fromServiceState) {
                setWifiCountryCodeFromMcc(context, mcc);
            } else {
                // from SIM
                try {
                    Configuration config = new Configuration();
                    boolean updateConfig = false;
                    if (mcc != 0) {
                        config.mcc = mcc;
                        config.mnc = mnc == 0 ? Configuration.MNC_ZERO : mnc;
                        updateConfig = true;
                    }

                    if (updateConfig) {
                        Slog.d(LOG_TAG, "updateMccMncConfiguration updateConfig config=" + config);
                        ActivityManagerNative.getDefault().updateConfiguration(config);
                    } else {
                        Slog.d(LOG_TAG, "updateMccMncConfiguration nothing to update");
                    }
                } catch (RemoteException e) {
                    Slog.e(LOG_TAG, "Can't update configuration", e);
                }
            }
        } else {
            if (fromServiceState) {
                // an empty mccmnc means no signal - tell wifi we don't know
                setWifiCountryCodeFromMcc(context, 0);
            }
        }
}
获取mcc和mnc,设置时区、设置wifi的iso以及最重要的通知更新ActivityManager有系统配置变了。在一个app的AndroidManifest.xml中,activity有个configChanges属性:
       <activity android:name="xxxxx"
                android:label="@string/xxx"
                android:configChanges="orientation|screenSize|keyboardHidden|mcc|mnc">
如果没有配置mcc和mnc,那么在这两个值有变化的时候Activity会重启,走OnDestroy然后走OnCreate。能引起这两个值变化的常用操作就是插拔SIM卡。知道mcc和mnc就能解释一些莫名其妙的bug。


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值