Reliable method to get the country the user is in?
Asked Answered
E

5

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.

Expiate answered 8/8, 2012 at 20:17 Comment(4)
Reverse geocoding would be possible, but may be overkill. I found Bing's easy and reliable.Albeit
With reverse geocoding you mean an approach like EboMike's in the thread I linked, right?Expiate
No, using the phones latitude and longitude through LocationManager to get the country of the point.Albeit
2021 This is not possible anymore with recent privacy lawsRavelin
S
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.

Sheehy answered 8/8, 2012 at 20:23 Comment(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?Expiate
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)").Sheehy
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.Expiate
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.....Expiate
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.Sheehy
2021 getSimCountryIso() is no moreRavelin
E
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.

Engram answered 8/8, 2012 at 20:38 Comment(7)
Ok, thanks for the more complete code, but this is principially the same as Eric's suggestion isnt it?Expiate
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?Engram
"the simcard from the country of origin" what exactly do you mean? Origin from what...? TelephonyManager.getSimCountryIso() returns the SIM provider's country code.Expiate
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.Engram
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.Expiate
Ah, and no, I'm not focusing on devices with sim-cards. I wrote that in the original question.Expiate
what if i am roaming with my Indian sim card in UK? I still get India which is not rightFinstad
W
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.

Wellfounded answered 8/8, 2012 at 20:23 Comment(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.Expiate
C
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.

Cockloft answered 18/5, 2015 at 20:9 Comment(1)
2021 not possible anymore!Ravelin
I
-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();
    }

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

Immix answered 12/12, 2017 at 22:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.