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.

Community
  • 1
  • 1
User
  • 31,811
  • 40
  • 131
  • 232

5 Answers5

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.

Cat
  • 66,919
  • 24
  • 133
  • 141
  • 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 Aug 08 '12 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 Aug 08 '12 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 Aug 08 '12 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 Aug 10 '12 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 Aug 10 '12 at 19:08
  • 2021 getSimCountryIso() is no more – user1034912 Sep 10 '21 at 01:17
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.

t0mm13b
  • 34,087
  • 8
  • 78
  • 110
  • Ok, thanks for the more complete code, but this is principially the same as Eric's suggestion isnt it? – User Aug 08 '12 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 Aug 08 '12 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 Aug 08 '12 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 Aug 08 '12 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 Aug 08 '12 at 21:37
  • Ah, and no, I'm not focusing on devices with sim-cards. I wrote that in the original question. – User Aug 08 '12 at 21:43
  • what if i am roaming with my Indian sim card in UK? I still get India which is not right – Cyph3rCod3r Oct 04 '21 at 10:49
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.

D.A
  • 2,555
  • 1
  • 14
  • 10
  • 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 Aug 08 '12 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.

Shavi
  • 139
  • 1
  • 4
-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();
    }

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

abir-cse
  • 507
  • 3
  • 12