Android中的mcc和mnc

    xiaoxiao2021-03-25  198

    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。

    转载请注明原文地址: https://ju.6miu.com/read-8748.html

    最新回复(0)