4

I am building a Cordova app for android platform.

I need to get the user's country.

I know that the geolocalisation gives the GPS coordinates.

Is there a way to have the country without using any external API? if not possible what is the best solution?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189

4 Answers4

3

There's important difference from UX and legal perspective on what country do you need:

  1. Country of current location: use geolocation API and any mapping solution. This is the only reliable way to determine country of location, since detection by IP or SIM card may only identify the country of telecom provider. Note, that country of the current location is not the country of citizenship and it does not allow to determine user's language or locale preferences.
  2. Country as the context for localization: use ECMAScript Internationalization API[1] and cordova-globalization-plugin[2] as a fallback. Note, that these APIs do not provide location information at all: language and locale information are not the same as user's country (e.g. user may choose french locale and en_US language, while living in Monaco and being a citizen of Russia).
  3. Country of citizenship. In some cases, it is a critical information for your service (e.g. when personal data of the user collected by the client-server system has to be physically processed in the country of citizenship as required by laws). The only way to determine it is to ask the user and require the honest answer from him by your Terms of Service. Note, that country of citizenship does not determine localization settings or user's current location.

[1] http://www.ecma-international.org/ecma-402/1.0/

[2] https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-globalization/

Ivan Gammel
  • 652
  • 7
  • 17
2

I can think of a few options. The list is provided below and it is ordered by least effort needed and on the other hand how accurate will the information be.

  1. Use user's locale string provided by Globalization plugin, it may contain the country code next to language code such as "en-US" or "en-GB".

Usage

function successCallback(obj) {
    var locale = obj.value;
}
navigator.globalization.getPreferredLanguage(successCallback, errorCallback);
  1. Only for Android: Use plugin such as Device Information plugin which allows you to access the Android's Telephony Manager's information. From this information you are able to get the

Country ISO of your phone network provider

according to the plugin author. To use the plugin your code would look something like this

deviceInfo.get(function(result) {
    console.log("result = " + result); 
}, function() {
    console.log("error");
});

where the result will contain your netCountry called field as part of the string returned.

  1. Figure the GPS to country conversion by yourself based on the country borders as GPS. One possible map (dataset) is available [here](World Borders Dataset). I would though recommend just using some external API to give that information for you.
Roope Hakulinen
  • 7,326
  • 4
  • 43
  • 66
  • Thank you for your answer : 1- Cannot be trusted, I did a test from Morocco and I see that it gives en-US, I think that this information is related to settings not location. 2- This solution my help, but I see, when user disables his network I need to get the information about the country. 3- May be a solution, I was hoping for it already done by some one, but cannot find it.. – Cabtine Yassine Jan 06 '15 at 09:27
  • Well, no one said it was going to be easy if you really need to make it reliable. I am not aware of how the Geocoder mentioned by iwen works, but if it doesn't use online connection (as I assume it does) it would solve the option 3 locally. Only thing missing from that is the Cordova plugin which someone would need to write. At least I haven't seen one for that purpose. – Roope Hakulinen Jan 06 '15 at 09:29
  • 1
    Globalization plugin should not be used to determine user's country except the only case when the goal is to localize the UX and the country information is not really needed. Neither globalization plugin nor ECMAScript I18n API does not provide country information. The language, selected by user, can be completely unrelated to his country, so decoding it is a complete waste of time. – Ivan Gammel Dec 18 '16 at 10:09
1

If your app is only for phone or device with sim, you can use sim info plugin, https://github.com/dtmtec/cordova-plugin-carrier.

sulaiman sudirman
  • 1,826
  • 1
  • 24
  • 32
-3

A simple solution is create a custom plugin and use Google geocoder, this code return location from latitude and longitude... This isn't for cordova, you need make some changes

try {
   Geocoder gcd = new Geocoder(this, Locale.getDefault());
   List<Address> addresses = gcd.getFromLocation(latitude, longitude, 1);
         if (addresses.size() > 0)
         String cityname = addresses.get(0).getLocality();
         String country = addresses.get(0).getCountryName();
} catch (IOException e) {
     e.printStackTrace();
}
Ivan
  • 978
  • 6
  • 13
  • Thank you for your answer, the issue with geocoder, is in order to use this service displaying a map is mandatory, whereas I don't need to display this map. – Cabtine Yassine Jan 06 '15 at 09:15
  • you don't need display a map, I used it without map – Ivan Jan 06 '15 at 09:22
  • On this page : https://developers.google.com/maps/documentation/geocoding/ The Geocoding API may only be used in conjunction with a Google map; geocoding results without displaying them on a map is prohibited. For complete details on allowed usage, consult the Maps API Terms of Service License Restrictions. – Cabtine Yassine Jan 06 '15 at 09:31
  • Maybe I'm wrong (tell me pls), but your link it's not correct. Geocoding web API want that map is displayed, but if you look the example inside link there are web call to convert or another Java Lib. In this link developer.android.com/reference/android/location/Geocoder.html (doc about Geocoder object) I don't see mandatory about map... Another point, if you look the java lib inside your link I see GeoApiContext context = new GeoApiContext().setApiKey("AIza...");. The code above (my) doesn't require any apikey so maybe I'm wrong but I think that your link is about other API, what do u think? – Ivan Jan 06 '15 at 14:42
  • Sorry Iwen, I tought you meant google maps API for web. So we are not talking about the same thing. And I think that the solution you propose may help also(even though I am not used to plugin dev, but I may consider it). Thank you! – Cabtine Yassine Jan 07 '15 at 13:07