19

I usually get the country from the device's language. It works but now I have to recognize Brazil. And most of the devices only have portuguese (pt_PT), and no portuguese (Brazil) option.

I checked this thread: Where am I? - Get country

The methods

 String locale = context.getResources().getConfiguration().locale.getCountry();

 String locale = context.getResources().getConfiguration().locale.getDisplayCountry();

Are still language-only, doesn't help.

There's also the suggestion with the sim-card, but I'm not sure if this will work reliably (do all sim cards have this unique identification?), it's also a bit not exactly what I need because the user can't change it (which is the case if it was a setting), and it will exclude users using a device without sim-card (maybe they just use WLAN).

There's also geolocation suggestion, but this will probably not work in devices which have deactivated it. Or am I wrong?

If nothing else helps I would make a dialog or menu setting in my app so the user can select it there. But I would first like to confirm if there's any reliable possibility with the device.

4
  • Reverse geocoding would be possible, but may be overkill. I found Bing's easy and reliable.
    – Tony
    Commented Aug 8, 2012 at 20:22
  • With reverse geocoding you mean an approach like EboMike's in the thread I linked, right?
    – User
    Commented Aug 8, 2012 at 21:05
  • No, using the phones latitude and longitude through LocationManager to get the country of the point.
    – Tony
    Commented Aug 9, 2012 at 6:24
  • 2021 This is not possible anymore with recent privacy laws Commented Sep 10, 2021 at 1:18

5 Answers 5

33

You can pull the location from the phone network:

TelephonyManager.getNetworkCountryIso()

Or from the SIM card:

TelephonyManager.getSimCountryIso()

Or, if you have the user's phone number, you may be able to match it to the country through this data.

Ideally, you could use all three of these (in some order, perhaps SIM, Phone #, then Network), and if none works, use reverse geolocation as a last resort.

6
  • But getNetworkCountryIso seems to depend also mainly on the SIM card, or...? "Only when user is registered to a network" Or which networks can these be?
    – User
    Commented Aug 8, 2012 at 20:59
  • It depends on what carrier network you are connected to. Every one has a country code attached to it (as the docs put it, it returns the "current registered operator's MCC (Mobile Country Code)").
    – Cat
    Commented Aug 8, 2012 at 21:01
  • 1
    Ok, thanks for your advice. I'll try first with language, if not enough info, the phone / network, then geolocation and if still not enough, show a custom dialog. That will cover all the cases.
    – User
    Commented Aug 8, 2012 at 21:40
  • 1
    Hm. But geolocation needs to add a permission. And it will be probably negative if all the users see geolocation permission. Specially if I need it only for certain Brasilian users.....
    – User
    Commented Aug 10, 2012 at 13:38
  • Well you can state this in your app summary, or simply skip the geolocation and go right to the dialog. The Brazilian users would probably think nothing of it.
    – Cat
    Commented Aug 10, 2012 at 19:08
7

Try this:

 TelephonyManager teleMgr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
 if (teleMgr != null){
     countryISOCode = teleMgr.getSimCountryIso();
 }

Now, countryISOCode would contain one of the following similar to the ISO 3166 country codes as per this Wikipedia entry.

7
  • Ok, thanks for the more complete code, but this is principially the same as Eric's suggestion isnt it?
    – User
    Commented Aug 8, 2012 at 21:09
  • Well its more accurate as its tied to the simcard from the country of origin - but... be careful, if its a tablet that does not have a simcard, null will be returned. in that case a fallback would be required, unless you're focussing on smartphones with sim-cards?
    – t0mm13b
    Commented Aug 8, 2012 at 21:19
  • "the simcard from the country of origin" what exactly do you mean? Origin from what...? TelephonyManager.getSimCountryIso() returns the SIM provider's country code.
    – User
    Commented Aug 8, 2012 at 21:27
  • 2
    if the simcard is bought in spain, it will have the spanish country code, likewise if the simcard is bought in the UK, it will have the UK code.
    – t0mm13b
    Commented Aug 8, 2012 at 21:32
  • Mh... ok, does this mean that TelephonyManager.getSimCountryIso() will return the code where the SIM card is currently registered? I need the most up to date information about the location of the user, where the SIM card was bought is not important, unless it's the only information available. For now +1 for useful input.
    – User
    Commented Aug 8, 2012 at 21:37
1

Geolocation would be the most effective and unobtrusive. You could always use geolocation, and if the user has it disabled display your dialog asking for their country. The less you bug the user for information the better.

1
  • Well, yes, maybe I do a few "steps down", first try with the language, then try with the sim card, then geolocation, and use the dialog as the last resort, if I still have ambiguous information.
    – User
    Commented Aug 8, 2012 at 21:02
1
TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
mTelephonyManager.getNetworkCountryIso();

As answered by Eric, the above code is the best approach. It is also worth noting that,

mTelephonyManager.getSimCountryIso()

should not be used as this would indicate the home country of the SIM provider (E.g. A Vodaphone UK SIM would return "gb", A Vodaphone Germany SIM would return "de") and not the current location (Country) of the device. This difference is significant when the user is roaming.

1
  • 2021 not possible anymore! Commented Sep 10, 2021 at 1:19
-1

It's working on me.

String countryISOCode;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TelephonyManager teleMgr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
    if (teleMgr != null){
        countryISOCode = teleMgr.getSimCountryIso();
    }

............................

Not the answer you're looking for? Browse other questions tagged or ask your own question.