Android MCC and MNC
Let me share some information with you.. It may help.
MCC, MNC, PLMN
First, you must understand MCC and MNC:
MCC - Mobile Country Code
This is the country code. It always has 3 digits. Some countries can use more than one MCC.MNC - Mobile Network Code
This is the network code. It can have 2 or 3 digits.MCCMNC - PLMN Number.
Those numbers are used to differentiate one carrier from another one.
For example, you can check a list at www.mcc-mnc.com:
AT&T in US has following PLMN Number:
MCC = 310
MNC = 410
PLMN = 310410
Telefonica in Brazil, for example, has following PLMN Number:
MCC = 724
MNC = 10
PLMN = 72410
Based on the information above, we can imagine that we have PLMNs with 5 or 6 digits.
Since MNC can have 2 or 3 digits, I think you can retrieve the MNC number as follows (knowing that MCC always have 3 digits):
String plmn = "33402"; // OR 334020
String mcc = plmn.substring(0,3);
String mnc = plmn.substring(3,plmn.length());
System.out.println("plmn[" + plmn + "] mcc[" + mcc + "] mnc[" + mnc + "]");
All carriers in same country share the same MCC numbers. Some countries has more than one MCC... But even then, all carriers in that country uses one of that MCC.
So, if you want to check the location of some carrier, you must read its MCC (and never its MNC).
SIM and Network
One information stored in the simcard is that PLMN number. The PLMN number is retrieved from its IMSI. Its PLMN number are the 5 or 6 first digits of its IMSI.
This way, you can determine which carrier owns that SIMCard.
On the other rand, the network tower also broadcast its PLMN.
This way, an device can search for its HOME network every time you reboot you device (or move to another location).
HOME vs ROAMING
Home situation is when PLMN Number from the simcard is the same of the current registered network.
Roaming is when the SIMCard has a different PLMN than the registered cell.
Of course, some carriers has more than one PLMN Number and phone should be considered HOME in those situations. But this is another story.
Finally getSimOperator() and getNetworkOperator()
getSimOperator()
This method returns MCCMNC (PLMN) from SIMCard
getNetworkOperator()
This method returns MCCMNC (PLMN) from current camped Carrier
It is up to you
Now, you know the difference between simcard and network operator. So, you have to decide how to block/allow your app.
If you block by
getSimOperator()
you are blocking the simcards from a specific country. This way, regarless the registered cell, feature will remain blocked (even if the user is travelling to a country with the feature enabled).If you block by
getNetworkOperator()
you are blocking the feature in specific networks/Contries. This way, if the user which can use the app, may have issues when he travells to a country where the feature is blocked.
iGoDa
Updated on July 02, 2022Comments
-
iGoDa almost 2 years
I'm trying to get the
mcc
andmnc
after aSIM LOADED
state, in order to check if the SIM card did change withoutREAD PHONE STATE
permissions, in order to disable the app requests for some networks and in some countries that the user do not want.Since
getSimOperator()
may change according to the current carrier (e.g. when the user is on roaming or not) I decided to use thegetNetworkOperator()
.Although this method can return
null
even if theSIM
isLOADED
and may return different results e.g. a lycamobile card with GSM only connection is giving memnc = 01
and when I take the SIM card out and put it again it gives memnc = 04
.Does some one know why the mnc gives different results for the
getNetworkOperator()
? Which method is better,getNetworkOperator()
orgetSimOperator()
for this case?Also, I cannot use
getResources().getConfiguration().mcc
because it gives a int number which might remove the0
before e.g. gives4
instead of04
.This is my code to check a SIM state change:
@Override public void onReceive(final Context context, Intent intent) { if (intent != null) { Bundle extras = intent.getExtras(); if (extras != null) { String ss = extras.getString(EXTRAS_SIM_STATUS); if (ss != null && (ss.equals("LOADED"))) { TelephonyManager telephonyManager = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && hasPermissions(READ_PHONE_STATE)) { //here I get the imsi }else{ L.d("NetworkOperator result %s", telephonyManager.getNetworkOperator()); //saving in shared preferences in order to check if the sim is allowed or not //this is also called on application onCreate() so I can check the current SIM } } } } }
PS: the SIM card that I'm using only has GSM connection. Also I tried with an other card (with 4g capabilities) and everything works as expected the
mnc
is the same01
for a vodafone card. -
iGoDa almost 8 yearsMarking as correct because clarified pretty well my doubts on the matter, thanks!