说明
本篇用于记录一个简单的通过ip地址解析定位的方法,主要是为了便于记忆,代码为主.
ip解析
通过ip解析地址,我采用的是网上免费的ip解析接口freegeoip,为github开源项目,采用的是免费的开源ip库。解析准确率较高,ip库也较为丰富(就目前而言,比淘宝等的接口的ip库包含数量大)。
freegeoip介绍
freegeoip的实现是通过go完成的,可以直接安装在自己的机器,也可以使用其提供的免费接口:http://freegeoip.net/ 。格式如下:
/*
*data_type:为请求返回数据格式,目前支持:json和xml
*ip_address:请求解析ip地址,可以为域名格式,也可以不填,默认为发起
*请求地址
*http://freegeoip.net/json/www.baidu.com
*/
String URL=
“http://freegeoip.net/(data_type)/(ip_address)”
1) 返回数据格式
数据返回格式为两种json或xml,如下:
json格式
{"ip":"103.235.46.39","country_code":"HK","country_name":"Hong Kong","region_code":"","region_name":"","city":"Central District","zip_code":"","time_zone":"Asia/Hong_Kong","latitude":22.291,"longitude":114.15,"metro_code":0}
xml格式
<Response>
<IP>103.235.46.39</IP>
<CountryCode>HK</CountryCode>
<CountryName>Hong Kong</CountryName>
<RegionCode/>
<RegionName/>
<City>Central District</City>
<ZipCode/>
<TimeZone>Asia/Hong_Kong</TimeZone>
<Latitude>22.291</Latitude>
<Longitude>114.15</Longitude>
<MetroCode>0</MetroCode>
</Response>
2) 返回参数
返回数据参数包括:请求IP、经纬度、当前的城市名称、城市编码、时区等信息。如下,为一些基本的参数信息介绍(以json格式为例,xml类似)。
参数名 | 数据格式 | 参数说明 |
---|---|---|
ip | 103.235.46.39 | 请求IP |
country_code | CN | 国家(地区)编码 |
country_name | China | 国家(地区)名称 |
region_code | 31 | 地区(省级,Hong_Kong不包含)编码 |
region_name | Shanghai | 地区名称(省级) |
city | Shanghai | 城市名称 |
zip_code | (基本没有获取成功过) | 邮政编码 |
time_zone | Asia/Shanghai | 时区 |
latitude | 31.0456 | 纬度 |
longitude | 121.3997 | 经度 |
metro_code | 0(基本都是0) | 地铁代码 |
ip解析实现
如下,为基本的ip地址解析使用(为实现的主要代码).
/**
*位置信息
*/
public class LatLng {
private double latitude; //纬度
private double longitude;//经度
private String country;
private String enCountry;
private String countryCode;
private String city;
private String enCity;
private String cityCode;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getEnCountry() {
return enCountry;
}
public void setEnCountry(String enCountry) {
this.enCountry = enCountry;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getEnCity() {
return enCity;
}
public void setEnCity(String enCity) {
this.enCity = enCity;
}
public String getCityCode() {
return cityCode;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
private Type type=Type.NORMAL;
/**
* 控制LatLng的类型
*/
public enum Type{
NORMAL("normal"),
GEO_LATLNG("geo");
private final String type;
private Type(String type){
this.type=type;
}
@Override
public String toString() {
return this.type;
}
}
public LatLng(){
}
/**
*
* @param latitude 纬度
* @param longitude 经度
*/
public LatLng(double latitude,double longitude){
this(latitude,longitude,Type.NORMAL);
}
public LatLng(double latitude,double longitude,Type type){
this(latitude,longitude,"","",type);
}
public LatLng(double latitude,double longitude,String country,String city){
this(latitude,longitude,country,city,Type.NORMAL);
}
public LatLng(double latitude,double longitude,String country,String city,Type type){
this(latitude,longitude,country,city,"","",type);
}
public LatLng(double latitude,double longitude,String country,String city,String enCountry,String enCity){
this(latitude,longitude,country,city,enCountry,enCity,Type.NORMAL);
}
public LatLng(double latitude,double longitude,String country,String city,String enCountry,String enCity,Type type){
this.latitude=latitude;
this.longitude=longitude;
this.country=country;
this.city=city;
this.enCountry=enCountry;
this.enCity=enCity;
this.type=type;
}
/**
* @return
*/
public boolean isGeoType(){
if (type==Type.GEO_LATLNG){
return true;
}
return false;
}
/**
*
* @return
* 返回String格式,用","分割
*/
public String geLocation(){
if (type==Type.NORMAL){
return latitude+","+longitude;
}else if (type==Type.GEO_LATLNG){
return longitude+","+latitude;
}else {
return null;
}
}
/**
* 自定义获取location格式
* @param type
* @return
*/
public String getLocation(Type type){
if (type==Type.NORMAL){
return latitude+","+longitude;
}else if (type==Type.GEO_LATLNG){
return longitude+","+latitude;
}else {
return null;
}
}
@Override
public String toString() {
return "LatLng{" +
"latitude=" + latitude +
", longitude=" + longitude +
", type=" + type +
'}';
}
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;
}
}
//如下为解析部分代码
/**
*
* @param urlPath
* @return get方式http请求获取返回值
*/
private ReqMessage getHttpGet(String urlPath){
HttpURLConnection connection=null;
ReqMessage reqMessage=null;
try {
URL url = new URL(urlPath);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("Accept-Charset", "utf-8");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// 建立实际的连接
connection.connect();
reqMessage=new ReqMessage(connection.getResponseCode(),connection.getResponseMessage(),connection);
// HllLogUtils.e(TAG,"reqMessage:"+reqMessage.toString());
if (reqMessage.getReq_code()==connection.HTTP_OK){
// HllLogUtils.e(TAG,"HTTP Request is success.");
HllLogUtils.i(TAG,"message content is:"+reqMessage.getContent());
}else {
HllLogUtils.e(TAG," HTTP Request is not success, Response code is "+reqMessage.getReq_code()+" ,and failed message is:" + reqMessage.getReq_message());
}
}catch (Exception e){
e.printStackTrace();
if (TextUtils.isEmpty(e.getMessage())){
// HllLogUtils.e(TAG,e.getMessage());
}
}finally {
if (connection!=null){
connection.disconnect();
}
}
if (reqMessage==null){
reqMessage=new ReqMessage();
}
return reqMessage;
}
/**
* 通过ip反向定位
* @return
*/
@Override
public LatLng loadIpGeoLocationInfo() {
ReqMessage reqMessage=getHttpGet(IP_GEO_LOCATION_DOMAIN);
LatLng latLng=null;
String country_code=null;
String country_name=null;
String city_name=null;
if (reqMessage!=null && !TextUtils.isEmpty(reqMessage.getContent())){
//获取解析返回
try {
JSONObject jsonObject = new JSONObject(reqMessage.getContent());
String latitude=jsonObject.getString("latitude");
String longitude=jsonObject.getString("longitude");
country_code=jsonObject.getString("country_code");
country_name=jsonObject.getString("country_name");
city_name=jsonObject.getString("city");
if (TextUtils.isEmpty(latitude) || TextUtils.isEmpty(longitude)) {
// HllLogUtils.e(TAG,"ip parse location error.");
}else if(this.latLng==null) {
latLng=new LatLng(Double.parseDouble(latitude.trim()), Double.parseDouble(longitude.trim()));
}else {
latLng=this.latLng;
}
}catch (JSONException jsonException){
jsonException.printStackTrace();
// HllLogUtils.e(TAG,jsonException.getMessage());
}
if (latLng!=null){
HllSharedPreferences hllSharedPreferences =new HllSharedPreferences(mContext);
hllSharedPreferences.setLatitude(latLng.getLatitude()+"");
hllSharedPreferences.setLongitude(latLng.getLongitude()+"");
this.latLng=latLng;
/**
* 处理国内外情况
*/
if (!TextUtils.isEmpty(country_code) && country_code.equals("CN")){
/**
* 中国
*/
hllSharedPreferences.setCountry("中国");
hllSharedPreferences.setEnCountry(country_name);
hllSharedPreferences.setEnCity(city_name);
loadLocationInfoCN();
}else {
/**
* 国外
*/
loadLocationInfoOverSeas();
}
}
}
return this.latLng;
}