How can I get a user's country location?
Asked Answered
T

6

21

Due to GDPR, I am requiring to check the user's location - whether the user is from the European Union. Till now I have found these solutions -

  1. Get Country using the Phone's language configuration (can misguide if the user uses English US version even though he might be from some other country).

     String locale = context.getResources().getConfiguration().locale.getCountry();
    
  2. Get Location using the GPS (requires the location coarse permission which I do not want to add especially because of Android 6.0+ runtime permissions).

     private void getCountryCode(final Location location) {
         Helper.log(TAG, "getCountryCode");
    
         AsyncTask<Void, Void, String> countryCodeTask = new AsyncTask<Void, Void, String>() {
    
             final float latitude = (float) location.getLatitude();
             final float longitude = (float) location.getLongitude();
             // Helper.log(TAG, "latitude: " + latitude);
             List<Address> addresses = null;
             Geocoder gcd = new Geocoder(mContext);
             String code = null;
    
             @Override
             protected String doInBackground(Void... params) {
                 try {
                     addresses = gcd.getFromLocation(latitude, longitude, 1);
                     code = addresses.get(0).getCountryCode();
                 } 
                 catch (IOException e) {
                     e.printStackTrace();
                 }
                 return code;
             }
    
             @Override
             protected void onPostExecute(String code) {
                 Helper.log(TAG, "onPostExecute");
                 mCountryCodeListener.returnCountryCode(code);
             }
         };
    
         if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
             countryCodeTask.execute();
         }
         else {
             countryCodeTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
         }
     }
    
  3. Get Location using the SIM card or Wi-Fi (can not be used on tables without SIM card or Wi-Fi, whereas my app can be used on the device without an Internet connection or Wi-Fi).

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

Is it possible to find out the location of the user if the user is from European Union region or not?

I do not need the exact location and even the country will work.

Is there another method which might also require location permission (not the coarse location permission will also be helpful)?

Please note that this question is not a duplicate of any other question as my case is not being solved by any other question.

Thiamine answered 9/5, 2018 at 12:25 Comment(2)
u got any solution ?Maui
@JithishPN Yes, you can use the IP Address of the user to find out from which country he is. Also, if you are interested to find only if the User is from EU or not then check the correct marked answer. For IP Address you can have a look at the below answer by VicJordan. You can try trimming out the last part of IP Address to make it Non Personal(I think it is possible, but please recheck it). Other ways are mentioned in the question. I know the service which gives you location from IP Address are paid but you can try searching for free one or build a simple one of your own. Hope this helps.Thiamine
C
16

You can check if user is in the EU by requesting the URL http://adservice.google.com/getconfig/pubvendors. It gives you an answer like this:

{"is_request_in_eea_or_unknown":true}

Somewhere I've read that it is the way the Android consent SDK works.

Cutlip answered 30/5, 2018 at 14:5 Comment(3)
Thanks for the answer. Sorry the bounty has been already awarded so cannot award it again. But does this service collect any info? Also does it store any info?Thiamine
No problem. I don't know if it stores any info, but I think they do not because Google use this approach in official consent SDK. I'm sure that they are aware of GDPR rules. The full source code is available on github: github.com/googleads/googleads-consent-sdk-androidCutlip
googleads-consent-sdk-android is deprecatedAnderlecht
J
3

You have mentioned all the possible options to get Country Name, but there is one more option. If your application has permission to access the Internet, you can get country name by IP address as well...

You can get the country name from the IP address as well. Once you have an IP address, pass that to the ipstack API to get the country name. You can make 10,000 requests/month for free.

There are many different ways to get an IP address (google it). One way is below:

public static String getLocalIpAddress() {
    try {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
            NetworkInterface intf = en.nextElement();
            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                    return inetAddress.getHostAddress();
                }
            }
        }
    } catch (SocketException ex) {
        ex.printStackTrace();
    }
    return null;
}

Add the below permission to AndroidManifest.xml:

 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Checkout this documentation for how to use the ipstack API: https://ipstack.com/documentation.

Usage:

https://api.ipstack.com/YOUR_IP_ADDRESS?access_key=YOUR_ACCESS_KEY

API response for 134.201.250.155 IP address in JSON format (you can get it in XML as well if you want):

{
  "ip": "134.201.250.155",
  "hostname": "134.201.250.155",
  "type": "ipv4",
  "continent_code": "NA",
  "continent_name": "North America",
  "country_code": "US",
  "country_name": "United States",
  "region_code": "CA",
  "region_name": "California",
  "city": "Los Angeles",
  "zip": "90013",
  "latitude": 34.0453,
  "longitude": -118.2413,
  "location": {
    "geoname_id": 5368361,
    "capital": "Washington D.C.",
    "languages": [
        {
          "code": "en",
          "name": "English",
          "native": "English"
        }
    ],
    "country_flag": "https://assets.ipstack.com/images/assets/flags_svg/us.svg",
    "country_flag_emoji": "🇺🇸",
    "country_flag_emoji_unicode": "U+1F1FA U+1F1F8",
    "calling_code": "1",
    "is_eu": false
  },
  "time_zone": {
    "id": "America/Los_Angeles",
    "current_time": "2018-03-29T07:35:08-07:00",
    "gmt_offset": -25200,
    "code": "PDT",
    "is_daylight_saving": true
  },
  "currency": {
    "code": "USD",
    "name": "US Dollar",
    "plural": "US dollars",
    "symbol": "$",
    "symbol_native": "$"
  },
  "connection": {
    "asn": 25876,
    "isp": "Los Angeles Department of Water & Power"
  }
  "security": {
    "is_proxy": false,
    "proxy_type": null,
    "is_crawler": false,
    "crawler_name": null,
    "crawler_type": null,
    "is_tor": false,
    "threat_level": "low",
    "threat_types": null
  }
}
Jesusa answered 15/5, 2018 at 2:4 Comment(1)
Thanks for your answer. But I want to check the users location before getting the privacy consent(Which is allowed under GDPR). Hence sending the user IP Address to any other service is not want what I would prefer but incase there is any other solution which can process the location without storing the IP Address but only using it within the phone itself will be really helpful. Also is it possible to get the country/region using the corse location permission only so that in Android 6+ I need not have to ask for runtime location permission?Thiamine
T
3

Use the Google Consent SDK to check if the user is in the European Economic Area (EEA).

In build.gradle, add:

implementation 'com.google.android.ads.consent:consent-library:1.0.6'

Use ConsentInformation.getInstance(context).requestConsentInfoUpdate( ... ) as described in the documentation.

Then use:

ConsentInformation.getInstance(context).isRequestLocationInEeaOrUnknown()

If the function returns true, apply GDPR rules to your app.

Tani answered 14/11, 2018 at 6:7 Comment(1)
Thanks for the answer. Will surely try this way.Thiamine
N
2

If you don't have GPS functionality in your app and you want to add and use it just for this case, it affects the user experience and I would suggest that you should assume that the user is already in that region and do what you have to do.

Getting the location (and draining the battery) just for this case is an overkill.

Nelrsa answered 19/5, 2018 at 5:47 Comment(4)
Thanks for the answer. But since GDPR requires to verify the users age whether they are above the legal age to provide the consent. Do you have any idea how to overcome this situation? I cannot ask ever user his age as my app is an utility tool app and asking the age from every use might be seem right to the user and might affect the performance of the app.Thiamine
This is what mopub is doing for GDPR. You could show something like this.Nelrsa
I also suggest skimming through reddit's androiddev, there been a few good threads of people discussing the issue (link for the search here)Nelrsa
Really Thank You for the links will need some time to go through those. But can you please suggest the way to download the personal data of the user and opt out consent of the user when using Fabric and Google Analytics and AdMob. Any idea?Thiamine
A
0

You can fetch MCC/MNC code and as your interest is in country MCC (mobile country code) should suffice.

Alphonse answered 16/5, 2018 at 12:3 Comment(1)
Thank You very much for the answer, but will this work with tablet without an SIM or an mobile which is not connected to the internet and does not have an sim inserted?Thiamine
D
0

Another method to do it is tracking IP location, but this may not work if the user uses VPN or proxy.

Here is an exemple of IP location api service : https://ip-api.com/

Dumfound answered 25/8, 2020 at 12:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.