2019-10-20

Content overview

This article will give the method of obtaining carrier on Android, the difference of the results of several similar methods, and the effective method of obtaining carrier in the case of multiple cards. Finally, there is an additional way to get carrier information without asking for a device identification number. Provide a working demo source.

MCC and newsun focus

First of all, these two codes are required to obtain the operator.

MCC Mobile Country Code Mobile device Country Code MNC, Mobile Network Code. When MCC and MNC are strung together, they can be used to represent a unique mobile device operator. China’s MCC is 460, while MNC has more than one operator, such as 01, 06 and 09 in China Unicom. The current code table can be found on this wiki page.

We can build a class from the code table:

enum class NetworkOperator(val opName: String) {

    Mobile("Mobile"),
    Unicom("China unicom"),
    Telecom("Telecommunications"),
    Tietong("Iron"),
    Other("Other");

    companion object {
        /** * Return 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) {
            "Mobile" -> Mobile
            "China unicom" -> Unicom
            "Telecommunications" -> Telecom
            "Iron" -> Tietong
            else -> Other
        }
    }
}
Copy the code

You probably also know that there is an identifier called IMSI (not IMEI). The International Mobile Subscriber Identity (ISUBSCRIBER) can distinguish different users in cellular networks. It is made up of MCC, MNC and MSIN (Mobile Subscriber Identity, Mobile Subscription Identification Number. So IMSI = MCC + MNC + MSIN.

How to get

On Android, you first request the READ_PHONE_STATE permission, and then get the information through the TelephonyManager method. TelephonyManager has several similar approaches, which can also be confusing. The Demo lists the results of each method, so if you’re interested, try it out for yourself.

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()
Copy the code

The results on my device are as follows:

TelephonyManager. GetSimOperator () : 46009 / / the current traffic card, unicom TelephonyManager. GetSimOperatorName () : CMCC / / unicom TelephonyManager. GetNetworkOperator () : 46000 / / mobile, card a TelephonyManager. GetNetworkOperatorName () : CHINA MOBILE / / move TelephonyManager getSubscriberId () : 46002326951 - XXXX / / move, this is the IMSI, XXXX partly hidden by me to Operator name: CHINA unicomCopy the code

So if you get MCC+MNC, you can determine the operator.

The double card case

What if the device has dual cards? Let’s look at the result after switching data cards:

TelephonyManager. GetSimOperator () : 46002 / / the current traffic card, mobile TelephonyManager. GetSimOperatorName () : CMCC / / unicom, with getSimOperator () inconsistent results TelephonyManager. GetNetworkOperator () : 46000 / / MOBILE TelephonyManager. GetNetworkOperatorName () : CHINA MOBILE / / move TelephonyManager getSubscriberId () : 46002326951xxxx // Move Operator name: MoveCopy the code

By trying to find, TelephonyManager getSimOperator () method the results obtained is set up based on the current traffic card. The results of other methods have not changed, and even the information obtained is not uniform, so it can be said that it is not useful.

However, I am not sure how the results of these methods will look on different devices and roMs, just for reference. You can download the demo to see the results on your own device.

Methods that do not require permissions

We all know that Android loads different resource folders depending on device Settings. Typically, string resources in different languages are loaded depending on the language of the system. Android can also load different resources based on MCC and MNC.

In a flash, I added the -mcc460-mnc00 suffix to the VALUES folder, and then put the corresponding carrier name string in it to bypass the permission to obtain the carrier.

If you want to create a folder for each MNC, you need to create a folder for each MNC.

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

There are drawbacks to this method as well, otherwise I would have written this method first – there is no way to get the current data card information, the information is fixed.

The Demo source code

Run the following command to get the demo source code:

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