How can I get the country (or its ISO code)?

AndroidLocationCountry Codes

Android Problem Overview


What is the best way to get the country code?

As of now, I know two ways. One is to get by TelephonyManager and another by Locale. Which is another best and unique way to find the country code on Android?

Android Solutions


Solution 1 - Android

Try this:

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String countryCode = tm.getSimCountryIso();

Solution 2 - Android

There are always huge discussions about this, and I never understand why developers and companies go for the complex way. The language selected by the user, means the language he/she wants to see always in his/her phone. They don't intend to have apps in a different language than others or the system.

The choice is very straight forward: Use Locale (to get the language the user selected as preferred), or make your best to piss them off showing them information in a language they already said they don't want to see things in.

To get the country code use:

Locale.getDefault().getCountry();

Solution 3 - Android

Use:

TelephonyManager tm = (TelephonyManager)getSystemService(getApplicationContext().TELEPHONY_SERVICE);
String countryCode = tm.getNetworkCountryIso();

It is better than getSimCountryIso because getSimCountryIso depends on the operator to burn the country ISO into the SIM and it also supports CDMA networks.

Solution 4 - Android

You can use this code to get ISO 2:

Locale.getDefault().getCountry()

And this to get ISO 3:

Locale.getDefault().getISO3Country()

Solution 5 - Android

I solved it by IP Address. You can get the IP address of your phone. If you are using Wi-Fi then it will be the IP address of the Wi-Fi hotspot or IP address of your mobile service provider server, so from that IP address you can send to a web service or something to track the country of that IP address.

There are some sources (database) available if Internet which provides the country of IP address.

Here is the example http://whatismyipaddress.com/ip-lookup.

Solution 6 - Android

I think the IP address is the best way because it will give you the country where the phone is at the moment.

If you do it by

Locale.getDefault().getCountry();

you get the country where the user select the country, so you can have selected England, and you can be in Spain and maybe you need to know where he/she is at the moment.

Example: imagine that your app can buy something only in England. The user is from Spain, but he/she is on holidays in England and he/she wants to buy your product ... if you use

Locale.getDefault().getCountry();

that user won't be able to buy your product, so the IP address is the best way I think.

Solution 7 - Android

There is an excellent article by Reto Meier: http://android-developers.blogspot.com/2011/06/deep-dive-into-location.html

It describes different techniques to get the location of an Android device, including source code.

Next, when you have the location, it's easy to get the country for it - you can use an online web-service or offline database.

Solution 8 - Android

It's very hard to find the country without GPS and Google Services (China). TelephonyManager won't work if there isn't any SIM card in your phone.

And Locale won't work if a user in China set his/her language as English (the country you will be getting will be US or UK).

If your app requires an Internet connection then there is an option. You could use this API called ip-api. Please go through their documentation first if you are planing to use this.

There are other APIs like this freegeoip API.

Solution 9 - Android

Here is a complete example. Try to get country code from TelephonyManager (from a SIM card or CDMA devices), and if not available, try to get it from the local configuration.

private static String getDeviceCountryCode(Context context) {
    String countryCode;

    // Try to get the country code from the TelephonyManager service
    TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    if(tm != null) {
        // Query first getSimCountryIso()
        countryCode = tm.getSimCountryIso();
        if (countryCode != null && countryCode.length() == 2)
            return countryCode.toLowerCase();

        if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
            // Special case for CDMA devices
            countryCode = getCDMACountryIso();
        } else {
            // For 3G devices (with a SIM card), query getNetworkCountryIso()
            countryCode = tm.getNetworkCountryIso();
        }

        if (countryCode != null && countryCode.length() == 2)
            return countryCode.toLowerCase();
    }

    // If the network country is not available (tablets maybe), get the country code from the Locale class
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        countryCode = context.getResources().getConfiguration().getLocales().get(0).getCountry();
    } else {
        countryCode = context.getResources().getConfiguration().locale.getCountry();
    }

    if (countryCode != null && countryCode.length() == 2)
        return  countryCode.toLowerCase();

    // General fallback to "us"
    return "us";
}

@SuppressLint("PrivateApi")
private static String getCDMACountryIso() {
    try {
        // Try to get country code from SystemProperties private class
        Class<?> systemProperties = Class.forName("android.os.SystemProperties");
        Method get = systemProperties.getMethod("get", String.class);

        // Get homeOperator that contain MCC + MNC
        String homeOperator = ((String) get.invoke(systemProperties,
                "ro.cdma.home.operator.numeric"));

        // First three characters (MCC) from homeOperator represents the country code
        int mcc = Integer.parseInt(homeOperator.substring(0, 3));

        // Mapping just countries that actually use CDMA networks
        switch (mcc) {
            case 330: return "PR";
            case 310: return "US";
            case 311: return "US";
            case 312: return "US";
            case 316: return "US";
            case 283: return "AM";
            case 460: return "CN";
            case 455: return "MO";
            case 414: return "MM";
            case 619: return "SL";
            case 450: return "KR";
            case 634: return "SD";
            case 434: return "UZ";
            case 232: return "AT";
            case 204: return "NL";
            case 262: return "DE";
            case 247: return "LV";
            case 255: return "UA";
        }
    }
    catch (ClassNotFoundException ignored) {
    }
    catch (NoSuchMethodException ignored) {
    }
    catch (IllegalAccessException ignored) {
    }
    catch (InvocationTargetException ignored) {
    }
    catch (NullPointerException ignored) {
    }

    return null;
}

Also another idea is to try an API request like in this answer, or to use fine location.

References are here and here.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVishal PawarView Question on Stackoverflow
Solution 1 - AndroidSahil Mahajan MjView Answer on Stackoverflow
Solution 2 - AndroidJose L UgiaView Answer on Stackoverflow
Solution 3 - AndroidAsaf PinhassiView Answer on Stackoverflow
Solution 4 - AndroidBach VuView Answer on Stackoverflow
Solution 5 - AndroidVishal PawarView Answer on Stackoverflow
Solution 6 - AndroidD4rWiNSView Answer on Stackoverflow
Solution 7 - AndroidHitOdessitView Answer on Stackoverflow
Solution 8 - Androidsunil sunnyView Answer on Stackoverflow
Solution 9 - Androidradu_paunView Answer on Stackoverflow