如何获取用户的国家/地区位置?
How can I get a user's country location?
由于 GDPR,我需要检查用户的位置 - 用户是否来自欧盟。到目前为止,我已经找到了这些解决方案 -
Get Country using the Phone's language configuration(如果用户使用美国英语版本,即使他可能来自其他国家/地区,也会产生误导)。
String locale = context.getResources().getConfiguration().locale.getCountry();
Get Location using the GPS(需要 location coarse 权限,我不想添加,特别是因为 Android 6.0+ 运行时权限).
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);
}
}
Get Location using the SIM card or Wi-Fi(不能在没有SIM卡或Wi-Fi的桌子上使用,而我的应用程序可以在没有互联网连接或Wi-Fi的设备上使用-Fi).
TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
String countryCodeValue = tm.getNetworkCountryIso();
是否可以查到用户是否来自欧盟地区?
我不需要确切的位置,甚至国家也可以。
是否有其他方法可能也需要位置权限(不是粗略的位置权限也有帮助)?
请注意,这个问题不是任何其他问题的重复,因为我的情况没有被任何其他问题解决。
您已经提到了获得 Country Name
的所有可能选项,但还有一个选项。 如果您的应用程序具有访问互联网的权限,您也可以通过IP地址获取国家名称...
您也可以从 IP 地址中获取国家名称。获得 IP 地址后,将其传递给 ipstack API 以获取国家/地区名称。您可以免费制作10,000 requests/month
。
获取 IP 地址的方法有很多种(google)。一种方式如下:
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;
}
将以下权限添加到 AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
查看此文档以了解如何使用 ipstack API:https://ipstack.com/documentation。
用法:
https://api.ipstack.com/YOUR_IP_ADDRESS?access_key=YOUR_ACCESS_KEY
API 以 JSON 格式响应 134.201.250.155
IP 地址(如果需要,您也可以在 XML 中获取):
{
"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
}
}
您可以获取 MCC/MNC 代码,因为您对国家 MCC(移动国家代码)感兴趣。
如果您的应用程序中没有 GPS 功能,而您只想为此添加和使用它,这会影响用户体验,我建议您应该假设用户已经在该地区做你必须做的事。
只为这种情况获取位置(并耗尽电池)是一种矫枉过正。
您可以通过请求 URL http://adservice.google.com/getconfig/pubvendors 来检查用户是否在欧盟。它会给你这样的答案:
{"is_request_in_eea_or_unknown":true}
我在某处读到过 Android consent SDK 的工作方式。
使用 Google Consent SDK 检查用户是否在欧洲经济区 (EEA)。
在build.gradle
中添加:
implementation 'com.google.android.ads.consent:consent-library:1.0.6'
将ConsentInformation.getInstance(context).requestConsentInfoUpdate( ... )
用作described in the documentation。
然后使用:
ConsentInformation.getInstance(context).isRequestLocationInEeaOrUnknown()
如果函数 returns true
,请将 GDPR 规则应用于您的应用。
另一种方法是跟踪 IP 位置,但如果用户使用 VPN 或代理,这可能不起作用。
这是 IP 定位 api 服务的示例:
https://ip-api.com/
由于 GDPR,我需要检查用户的位置 - 用户是否来自欧盟。到目前为止,我已经找到了这些解决方案 -
Get Country using the Phone's language configuration(如果用户使用美国英语版本,即使他可能来自其他国家/地区,也会产生误导)。
String locale = context.getResources().getConfiguration().locale.getCountry();
Get Location using the GPS(需要 location coarse 权限,我不想添加,特别是因为 Android 6.0+ 运行时权限).
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); } }
Get Location using the SIM card or Wi-Fi(不能在没有SIM卡或Wi-Fi的桌子上使用,而我的应用程序可以在没有互联网连接或Wi-Fi的设备上使用-Fi).
TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); String countryCodeValue = tm.getNetworkCountryIso();
是否可以查到用户是否来自欧盟地区?
我不需要确切的位置,甚至国家也可以。
是否有其他方法可能也需要位置权限(不是粗略的位置权限也有帮助)?
请注意,这个问题不是任何其他问题的重复,因为我的情况没有被任何其他问题解决。
您已经提到了获得 Country Name
的所有可能选项,但还有一个选项。 如果您的应用程序具有访问互联网的权限,您也可以通过IP地址获取国家名称...
您也可以从 IP 地址中获取国家名称。获得 IP 地址后,将其传递给 ipstack API 以获取国家/地区名称。您可以免费制作10,000 requests/month
。
获取 IP 地址的方法有很多种(google)。一种方式如下:
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;
}
将以下权限添加到 AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
查看此文档以了解如何使用 ipstack API:https://ipstack.com/documentation。
用法:
https://api.ipstack.com/YOUR_IP_ADDRESS?access_key=YOUR_ACCESS_KEY
API 以 JSON 格式响应 134.201.250.155
IP 地址(如果需要,您也可以在 XML 中获取):
{
"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
}
}
您可以获取 MCC/MNC 代码,因为您对国家 MCC(移动国家代码)感兴趣。
如果您的应用程序中没有 GPS 功能,而您只想为此添加和使用它,这会影响用户体验,我建议您应该假设用户已经在该地区做你必须做的事。
只为这种情况获取位置(并耗尽电池)是一种矫枉过正。
您可以通过请求 URL http://adservice.google.com/getconfig/pubvendors 来检查用户是否在欧盟。它会给你这样的答案:
{"is_request_in_eea_or_unknown":true}
我在某处读到过 Android consent SDK 的工作方式。
使用 Google Consent SDK 检查用户是否在欧洲经济区 (EEA)。
在build.gradle
中添加:
implementation 'com.google.android.ads.consent:consent-library:1.0.6'
将ConsentInformation.getInstance(context).requestConsentInfoUpdate( ... )
用作described in the documentation。
然后使用:
ConsentInformation.getInstance(context).isRequestLocationInEeaOrUnknown()
如果函数 returns true
,请将 GDPR 规则应用于您的应用。
另一种方法是跟踪 IP 位置,但如果用户使用 VPN 或代理,这可能不起作用。
这是 IP 定位 api 服务的示例: https://ip-api.com/