A comprehensive note about Android getting operators

Keywords: Android Mobile network git

Time of publication: October 20, 2019

Content overview

This article will give the methods of getting operators on Android, the differences of several similar methods, and the effective ways of getting operators in the case of multiple cards. Finally, a method that does not need to request the device identification code to obtain the operator information is proposed. Provide the demo source code that can be run.

MCC and MNC

First of all, I will introduce these two codes, which are also necessary for acquiring operators.

MCC, Mobile Country Code. MNC, Mobile Network Code, mobile device network code. When MCC and MNC are linked together, they can be used to represent the only mobile device operator. China's MCC is 460, MNC will have more than one operator, for example, Unicom has 01, 06, 09. The current code table can be This wiki page Find it.

You can first build such a class according to the code table:

enum class NetworkOperator(val opName: String) {

    Mobile("move"),
    Unicom("Unicom"),
    Telecom("telecom"),
    Tietong("Tietong"),
    Other("Other");

    companion object {
        /**
         * Return to operator according to [code] (MCC+MNC)
         */
        fun from(code: Int) = when (code) {
            46000, 46002, 46004, 46007, 46008 -> Mobile
            46001, 46006, 46009 -> Unicom
            46003, 46005, 46011 -> Telecom
            46020 -> Tietong
            else -> Other
        }

        fun fromOpName(name: String) = when (name) {
            "move" -> Mobile
            "Unicom" -> Unicom
            "telecom" -> Telecom
            "Tietong" -> Tietong
            else -> Other
        }
    }
}

You probably know that there is an identification code called IMSI (note that it's not IMEI). The International Mobile Subscriber Identity can distinguish different users in the cellular network. It is composed of MCC, MNC and MSIN (mobile subscriber identity number). That is, IMSI = MCC + MNC + MSIN.

How to get

On Android, you need to request the read phone state permission first, and then get information through the related methods of the TelephonyManager. Telephone manager has several similar methods, which are also confusing. The result of each method will be listed in the Demo. You can try it yourself if you are interested.

val tm = getSystemService<TelephonyManager>()
val text = """
    TelephonyManager.getSimOperator(): ${tm.simOperator}
    TelephonyManager.getSimOperatorName(): ${tm.simOperatorName}
    TelephonyManager.getNetworkOperator(): ${tm.networkOperator}
    TelephonyManager.getNetworkOperatorName(): ${tm.networkOperatorName}
    TelephonyManager.getSubscriberId(): ${tm.subscriberId}
    Operator name: ${NetworkOperator.from(Integer.valueOf(tm.simOperator)).opName}
""".trimIndent()

The results on my device are as follows:

TelephonyManager.getSimOperator(): 46009                // Current flow card, Unicom
TelephonyManager.getSimOperatorName(): CMCC                // Unicom
TelephonyManager.getNetworkOperator(): 46000            // Move, card one
TelephonyManager.getNetworkOperatorName(): CHINA MOBILE  // move
TelephonyManager.getSubscriberId(): 46002326951xxxx         // Mobile, this is IMSI, xxxx part is hidden by me
Operator name: Unicom

Then, if MCC+MNC is obtained, the operator can be determined.

Double card situation

What if the device has dual cards? After switching the flow card, check the result again:

TelephonyManager.getSimOperator(): 46002                // Current flow card, moving
TelephonyManager.getSimOperatorName(): CMCC                // Unicom, inconsistent with getSimOperator() result
TelephonyManager.getNetworkOperator(): 46000            // move
TelephonyManager.getNetworkOperatorName(): CHINA MOBILE  // move
TelephonyManager.getSubscriberId(): 46002326951xxxx         // move
Operator name: move

The result obtained by the TelephonyManager.getSimOperator() method changes according to the currently set traffic card. The results of other methods have not changed, and even the information obtained is not uniform, so it is useless.

However, I am not sure about the effect of these methods on different ROM s of different devices, for reference only. You can download the demo to see the results on your device.

Method without permission

We all know that Android will load different resource folders according to different device settings. Most typically, string resources in different languages will be loaded according to the system language. Android can also load different resources according to MCC and MNC.

In a flash, I added the suffix - mcc460-mnc00 to the values folder, and then put the name string of the corresponding operator in it, so that I could get the operator without permission.

But wait a moment. It's very troublesome to write a folder for each MNC. Let's use code to get it:

val mcc = resources.configuration.mcc
val mnc = resources.configuration.mnc
val operator = NetworkOperator.from(mcc * 100 + mnc)

This method also has disadvantages, otherwise I will write this method in the front - I can't get the information of the current traffic card, and the information obtained is fixed.

Demo source code

Run the following command to get the source code for the demo:

git clone -b sim-operator https://github.com/Loong-T/demo.git

Posted by The Wise One on Sun, 20 Oct 2019 04:17:25 -0700