Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get a user's country location?

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.

like image 718
Rajesh K Avatar asked May 09 '18 12:05

Rajesh K


People also ask

How do I find the location of a user?

In order to get the last location of the user, make use of the Java public class FusedLocationProviderClient. It is actually a location service that combines GPS location and network location to achieve a balance between battery consumption and accuracy.

How do you detect a website visitor's country?

There are two very popular ways to detect a user's location in the browser directly: Using the Geolocation API. Looking up user IP address.

How do you get geolocation without permission?

You can go for an external service like https://www.geolocation-db.com. They provide a geolocation service based on IP addresses where you don't need user permission.

How do I find a country code from an IP address?

You can use https://ip-api.io for this task easily.


3 Answers

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.

like image 72
Bero Avatar answered Oct 11 '22 11:10

Bero


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
  }
}
like image 34
Vikasdeep Singh Avatar answered Oct 11 '22 10:10

Vikasdeep Singh


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.

like image 23
Paweł Nadolski Avatar answered Oct 11 '22 09:10

Paweł Nadolski