【问题标题】:How to determine location of device in Android using IP address如何使用 IP 地址在 Android 中确定设备的位置
【发布时间】:2012-12-15 13:57:45
【问题描述】:

我正在开发一个 Android 应用程序。我想使用设备的 IP 地址确定设备的位置。我从哪里开始? Google API 上的链接不够明确。谢谢。

【问题讨论】:

    标签: android geolocation


    【解决方案1】:

    我们可以通过简单的 API 调用来获取位置,但是准确率会很低。

    LocationApiService apiService = getGeoApiService();
        apiService.getLocation().enqueue(new Callback<GeoResponse>() {
            @Override
            public void onResponse(Call<GeoResponse> call, Response<GeoResponse> response) {
                response.body().getLatitude();
                response.body().getLongitude();
            }
    
            @Override
            public void onFailure(Call<GeoResponse> call, Throwable t) {
                t.getMessage();
            }
        });
    

    LocationApiService

    public interface LocationApiService {
        @GET("json")
        Call<GeoResponse> getLocation();
    }
    

    getGeoApiService()

    public static final String BASE_URL = "http://ip-api.com/";
    
    public static LocationApiService getGeoApiService() {
            return new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
                    .create(LocationApiService.class);
        }
    

    地理响应

    public class GeoResponse {
    
        private String as;
        private String city;
        private String country;
        private String countryCode;
        private String isp;
        @SerializedName("lat")
        private double latitude;
        @SerializedName("lon")
        private double longitude;
        private String org;
        private String query;
        private String region;
        private String regionName;
        private String timezone;
    
        @Override
        public String toString() {
            return "countryCode: " + countryCode + ", isp: " + isp + ", city: " + city;
        }
    
        public String getAs() {
            return as;
        }
    
        public void setAs(String as) {
            this.as = as;
        }
    
        public String getCity() {
            return city;
        }
    
        public void setCity(String city) {
            this.city = city;
        }
    
        public String getCountry() {
            return country;
        }
    
        public void setCountry(String country) {
            this.country = country;
        }
    
        public String getCountryCode() {
            return countryCode;
        }
    
        public void setCountryCode(String countryCode) {
            this.countryCode = countryCode;
        }
    
        public String getIsp() {
            return isp;
        }
    
        public void setIsp(String isp) {
            this.isp = isp;
        }
    
        public double getLatitude() {
            return latitude;
        }
    
        public void setLatitude(double latitude) {
            this.latitude = latitude;
        }
    
        public double getLongitude() {
            return longitude;
        }
    
        public void setLongitude(double longitude) {
            this.longitude = longitude;
        }
    
        public String getOrg() {
            return org;
        }
    
        public void setOrg(String org) {
            this.org = org;
        }
    
        public String getQuery() {
            return query;
        }
    
        public void setQuery(String query) {
            this.query = query;
        }
    
        public String getRegion() {
            return region;
        }
    
        public void setRegion(String region) {
            this.region = region;
        }
    
        public String getRegionName() {
            return regionName;
        }
    
        public void setRegionName(String regionName) {
            this.regionName = regionName;
        }
    
    
        public String getTimezone() {
            return timezone;
        }
    
        public void setTimezone(String timezone) {
            this.timezone = timezone;
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用freegeoip.net

      这是一项免费的开源服务。您可以直接使用该服务或在您的个人服务器上运行它。它也可以很容易地部署到 Heroku。

      要获取 IP 位置,只需使用 OkHttp 发送 http/https 请求:

      String url = "https://freegeoip.net/json/"
      Request mRequest = new Request.Builder()
              .url(url)
              .build();
      Context mContext // A UI context
      new OkHttpClient().newCall(mRequest).enqueue(new Callback() {
          Handler mainHandler = new Handler(mContext.getApplicationContext().getMainLooper());
      
          @Override
          public void onResponse(Call call, Response response) {
              String responseBody = null;
              try {
                  responseBody = response.body().string();
              } catch (final IOException e) {
                  mainHandler.post(new Runnable() {
                      @Override
                      public void run() {
                          // handle error
                      }
                  });
              }
      
              final String finalResponseBody = responseBody;
              mainHandler.post(new Runnable() {
                  @Override
                  public void run() {
                      // handle response body
                      try {
                          JSONObject locationObject = new JSONObject(finalResponseBody);
                      } catch (JSONException e) {
                          e.printStackTrace();
                      }
                  }
              });
          }
      
          @Override
          public void onFailure(Call call, final IOException e) {
              mainHandler.post(new Runnable() {
                  @Override
                  public void run() {
                      mNetworkListener.onNetworkError(e.getMessage());
                  }
              });
          }
      });
      

      响应将如下所示:

      {
          "ip": "192.30.253.113",
          "country_code": "US",
          "country_name": "United States",
          "region_code": "CA",
          "region_name": "California",
          "city": "San Francisco",
          "zip_code": "94107",
          "time_zone": "America/Los_Angeles",
          "latitude": 37.7697,
          "longitude": -122.3933,
          "metro_code": 807
      }
      

      【讨论】:

        【解决方案3】:

        结帐Google Maps Geolocation API

        POST 示例:

        https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY
        

        示例响应:

        {
          "location": {
            "lat": 51.0,
            "lng": -0.1
          },
          "accuracy": 1200.4
        }
        

        限制:

        标准 API 的用户:

        每天 2,500 次免费查询 每个用户每秒 10 个查询 启用即用即付计费以解锁更高的配额:

        0.50 美元/1000 次额外查询,每天最多 100,000 次。

        MORE

        【讨论】:

          【解决方案4】:

          我使用this 获取设备的ip、国家和城市

          您可以使用 RESTCLIENT 进行测试,这是用于发出 HTTP 请求的 firefox 插件。

          只需复制 https://addons.mozilla.org/en-us/firefox/addon/restclient/ 这个 URL 并在 RESTCLIENT 中测试或只是过去在浏览器地址栏中

          希望这会有所帮助!

          【讨论】:

            【解决方案5】:

            有几个网络服务,可以为您提供来自 IP 地址的纬度和经度值。

            其中之一是 api.ipinfodb.com

            例如,您可以通过发送请求来获得纬度和经度

             http://api.ipinfodb.com/v3/ip-city/?key=<your_api_key>
                           &ip=74.125.45.100&format=json
            

            这将返回 json 格式的数据,您可以通过设置 format=xml 以 XML 格式获取响应。(您需要注册以获取您的 API 密钥)。

            或者您可以从thisthis 链接下载数据库。

            您可以下载数据集,但您必须不断更新它。

            【讨论】:

            • 我已尝试获取此站点的 API 密钥,但未成功。即使我提供了它,它仍继续请求我的位置。您愿意分享您的密钥吗?
            猜你喜欢
            • 2018-01-05
            • 1970-01-01
            • 2019-02-24
            • 2022-11-22
            • 1970-01-01
            • 1970-01-01
            • 2022-01-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多