【问题标题】:How can I get a user's country location?如何获取用户的国家/地区位置?
【发布时间】:2023-12-16 04:38:01
【问题描述】:

由于GDPR,我需要检查用户的位置 - 用户是否来自欧盟。到目前为止,我已经找到了这些解决方案 -

  1. Get Country using the Phone's language configuration如果用户使用英文美国版,即使他可能来自其他国家/地区,也会误导)。

     String locale = context.getResources().getConfiguration().locale.getCountry();
    
  2. Get Location using the GPS需要粗略定位权限,我不想添加,特别是因为 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);
         }
     }
    
  3. Get Location using the SIM card or Wi-Fi不能在没有 SIM 卡或 Wi-Fi 的桌子上使用,而我的应用可以在没有互联网连接或 Wi-Fi 的设备上使用)。

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

如果用户来自欧盟地区,是否可以找出用户的位置?

我不需要确切的位置,甚至国家都可以。

是否有另一种方法也可能需要位置权限(不是粗略的位置权限也会有帮助)?

请注意,这个问题不是任何其他问题的重复,因为我的情况没有被任何其他问题解决。

【问题讨论】:

  • 你有什么解决办法吗?
  • @JithishPN 是的,您可以使用用户的 IP 地址来找出他来自哪个国家/地区。此外,如果您有兴趣仅查找用户是否来自欧盟,请检查正确标记的答案。对于 IP 地址,您可以查看 VicJordan 的以下答案。您可以尝试修剪 IP 地址的最后一部分以使其成为非个人(我认为这是可能的,但请重新检查)。问题中提到了其他方式。我知道从 IP 地址为您提供位置的服务是付费的,但您可以尝试搜索免费的服务或自己构建一个简单的服务。希望这会有所帮助。

标签: android geolocation location privacy android-gps


【解决方案1】:

您可以通过请求 URL http://adservice.google.com/getconfig/pubvendors 来检查用户是否在欧盟。它会给你这样的答案:

{"is_request_in_eea_or_unknown":true}

我在某处读到,这是 Android 许可 SDK 的工作方式。

【讨论】:

  • 感谢您的回答。抱歉,赏金已经发放,因此无法再次发放。但是这项服务会收集任何信息吗?它还存储任何信息吗?
  • 没问题。我不知道它是否存储任何信息,但我认为它们没有,因为谷歌在官方许可 SDK 中使用了这种方法。我确信他们知道 GDPR 规则。完整的源代码在 github 上:github.com/googleads/googleads-consent-sdk-android
  • googleads-consent-sdk-android 已弃用
【解决方案2】:

您已经提到了获取Country Name 的所有可能选项,但还有一个选项。 如果您的应用程序有权访问 Internet,您也可以通过 IP 地址 获取国家/地区名称...

您也可以从 IP 地址中获取国家/地区名称。获得 IP 地址后,将其传递给 ipstack API 以获取国家/地区名称。您可以免费制作10,000 requests/month

获取 IP 地址的方法有很多种(谷歌搜索)。一种方法如下:

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

134.201.250.155 IP 地址的 API 响应,JSON 格式(如果需要,您也可以在 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
  }
}

【讨论】:

  • 感谢您的回答。但是我想在获得隐私同意之前检查用户的位置(这在 GDPR 下是允许的)。因此,将用户 IP 地址发送到任何其他服务并不是我想要的,但如果有任何其他解决方案可以在不存储 IP 地址的情况下处理该位置,但仅在手机本身内使用它会非常有帮助。是否也可以仅使用 corse 位置权限来获取国家/地区,以便在 Android 6+ 中我无需请求运行时位置权限?
【解决方案3】:

使用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()

如果函数返回 true,请将 GDPR 规则应用于您的应用。

【讨论】:

  • 感谢您的回答。一定会尝试这种方式。
【解决方案4】:

如果您的应用中没有 GPS 功能,并且您只想为此情况添加和使用它,它会影响用户体验,我建议您应该假设用户已经在该地区并执行你必须做什么。

仅针对这种情况获取位置(并耗尽电池电量)是一种矫枉过正。

【讨论】:

  • 感谢您的回答。但由于 GDPR 要求验证用户年龄是否超过法定年龄才能提供同意。你知道如何克服这种情况吗?我不能问任何用户他的年龄,因为我的应用是一个实用工具应用,每次使用时询问年龄对用户来说可能是正确的,并且可能会影响应用的性能。
  • This 是 mopub 为 GDPR 所做的事情。你可以展示这样的东西。
  • 我也建议浏览一下reddit的androiddev,有一些人讨论这个问题的好帖子(搜索链接here
  • 非常感谢您提供的链接需要一些时间才能完成。但是,您能否建议在使用 Fabric、Google Analytics 和 AdMob 时下载用户的个人数据并选择退出用户同意的方式。有什么想法吗?
【解决方案5】:

您可以获取 MCC/MNC 代码,并且由于您对国家/地区感兴趣,因此 MCC(移动国家代码)就足够了。

【讨论】:

  • 非常感谢您的回答,但这是否适用于没有 SIM 卡的平板电脑或未连接到互联网且未插入 SIM 卡的手机?
【解决方案6】:

另一种方法是跟踪 IP 位置,但如果用户使用 VPN 或代理,这可能不起作用。

这里是一个 IP 定位 api 服务的例子: https://ip-api.com/

【讨论】:

    最近更新 更多