8

I want to get device country code with out using sim card.

e.g If Country : Sri lanka Country code : LK

my final goal is get calling code (+94 for sri lanka)

i tried with this

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

but this return empty string

USER9561
  • 1,084
  • 3
  • 15
  • 41
ayesh don
  • 1,121
  • 1
  • 15
  • 25
  • 1
    USe these it might helpful for you:--TelephonyManager.getNetworkCountryIso() – Ravindra Kushwaha Mar 04 '16 at 06:51
  • may below link help you out http://stackoverflow.com/questions/5402253/getting-telephone-country-code-with-android – Damodhar Mar 04 '16 at 06:52
  • Have a look at this: http://stackoverflow.com/a/11872569/5352802 – camelCaseCoder Mar 04 '16 at 06:53
  • I tried with tm.getNetworkCountryIso(); but its return empty string. in my didn't have sim card.only wifi. – ayesh don Mar 04 '16 at 06:55
  • You can use this http://maps.googleapis.com/maps/api/geocode/json?latlng=7.0000,81.0000&sensor=false for getting country code ..The short name will give you country code .. But you need to get the current lat and long .. – Sunil Sunny Mar 04 '16 at 07:10

5 Answers5

4

It's returning an empty string because the device doesn't have a sim card.

You might be able to use the device's current locale:

Locale current = getResources().getConfiguration().locale;

but that's not necessarily going to be the same as what you'd get by looking at the carrier iso and the user can update that in the settings whenever they want to whatever they want. As pointed out, you can also ask the location manager for the user's coordinates. But remember, users move around and their current location may not always correspond to their carrier's iso.

Community
  • 1
  • 1
dcow
  • 7,765
  • 3
  • 45
  • 65
  • 1
    Thanks fried. i tried this one also but it always return "US". – ayesh don Mar 04 '16 at 06:59
  • 1
    @ayeshdon that's because the local is set to US. I repeat, you ***cannot*** get the carrier `iso` *without* a sim card. – dcow Mar 04 '16 at 07:05
  • 1
    This will return the country of the Locale that the user configured. If the user configures the device for India and then takes it on a plane to Germany, you'll still get the country code for India. Just thought I would clarify that. – Sunil Sunny Mar 04 '16 at 09:07
4

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

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

    // try to get country code from 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 SIM) query getNetworkCountryIso()
            countryCode = tm.getNetworkCountryIso();
        }

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

    // if network country not available (tablets maybe), get country code from 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 3 chars (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.

And in order to get country prefix you can use LibPhoneNumber library from Google.

References here and here

radu_paun
  • 1,940
  • 21
  • 25
0

You can use this http://maps.googleapis.com/maps/api/geocode/json?latlng=7.0000,81.0000&sensor=false for getting country code ..The short name will give you country code ..

 public void getAddress(double lat,double lng) {
    Address1 = "";
    Address2 = "";
    City = "";
    State = "";
    Country = "";
    County = "";
    PIN = "";

    try {

        JSONObject jsonObj = JsonParser.getJSONfromURL("http://maps.googleapis.com/maps/api/geocode/json?latlng=" + lat + ","
                +lng + "&sensor=false");
        String Status = jsonObj.getString("status");
        if (Status.equalsIgnoreCase("OK")) {
            JSONArray Results = jsonObj.getJSONArray("results");
            JSONObject zero = Results.getJSONObject(0);
            JSONArray address_components = zero.getJSONArray("address_components");

            for (int i = 0; i < address_components.length(); i++) {
                JSONObject zero2 = address_components.getJSONObject(i);
                String long_name = zero2.getString("long_name");
                String short_name = zero2.getString("short_name");
                JSONArray mtypes = zero2.getJSONArray("types");
                String Type = mtypes.getString(0);

                if (TextUtils.isEmpty(long_name) == false || !long_name.equals(null) || long_name.length() > 0 || long_name != "") {
                    if (Type.equalsIgnoreCase("street_number")) {
                        Address1 = long_name + " ";
                    } else if (Type.equalsIgnoreCase("route")) {
                        Address1 = Address1 + long_name;
                    } else if (Type.equalsIgnoreCase("sublocality")) {
                        Address2 = long_name;
                    } else if (Type.equalsIgnoreCase("locality")) {
                        // Address2 = Address2 + long_name + ", ";
                        City = long_name;
                    } else if (Type.equalsIgnoreCase("administrative_area_level_2")) {
                        County = long_name;
                    } else if (Type.equalsIgnoreCase("administrative_area_level_1")) {
                        State = long_name;
                    } else if (Type.equalsIgnoreCase("country")) {
                        Country = short_name;
                    } else if (Type.equalsIgnoreCase("postal_code")) {
                        PIN = long_name;
                    }
                }

                // JSONArray mtypes = zero2.getJSONArray("types");
                // String Type = mtypes.getString(0);
                // Log.e(Type,long_name);
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

}

But you need to get the current lat and long ..

Use this link for getting the current lat and lng

http://gabesechansoftware.com/location-tracking/

Sunil Sunny
  • 3,949
  • 4
  • 23
  • 53
  • What if I'm not in my carrier's country? – dcow Mar 04 '16 at 07:44
  • He asked for the device country code without using sim card and this is the only option I guess. And you are right ,if user's carrier country and current country are different then this won't work. – Sunil Sunny Mar 04 '16 at 09:01
  • Sometime between then and now Google changed it to require an API KEY to be added to the URL. It will look something like `&key=...` if tacked on the end. – Jesse Chisholm Mar 08 '19 at 00:10
0

In my case telephonyManager.getNetworkCountryIso() is returning empty as i have two sim slots, you can pass slot as parameter if it returns "". Simply change your code to:

 String iso=telephonyManager.getNetworkCountryIso();
       if(TextUtils.isEmpty(iso))
           iso=telephonyManager.getNetworkCountryIso(1);
       if(TextUtils.isEmpty(iso))
           iso=telephonyManager.getNetworkCountryIso(2);

// this code will give preference to Sim Slot 1
zeenosaur
  • 888
  • 11
  • 16
Satyam Anand
  • 377
  • 1
  • 8
-6
  1. get iso country code => US
  2. lookup this table => 1 https://countrycode.org/
Khanh Tran
  • 37
  • 5