How can I get a user's country location?

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.


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
  }
}

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.