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
Android中相关的代码在telephony framwork中,主要是frameworks/opt/telephony/src/java/com/android/internal/telephony/MccTable.java。
static {
sTable = new ArrayList(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 {
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;
}
}
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最终确定时区。
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属性:
如果没有配置mcc和mnc,那么在这两个值有变化的时候Activity会重启,走OnDestroy然后走OnCreate。能引起这两个值变化的常用操作就是插拔SIM卡。知道mcc和mnc就能解释一些莫名其妙的bug。