sheldon_blogs

Android : 基于公网IP和第三方数据库进行时区自动同步

一、前言

  电子移动设备在区域变更时需要根据地区坐标进行时间、时区的同步,目前普遍使用的手机可以利用网络同步时间,进一步通过运营商信息、GPS等获取位置信息来进行时区同步。而有的电子设备,如:智能TV、教育机 虽然可以联网,但没有GPS模块,无法获取位置信息,只能手动设置时区。

  本文介绍一种通过第三方服务器获取公网IP和数据库查询进行时区定位及自动更新的方法。

 

二、公网IP获取

  通过HttpURL访问某些企业服务器,如:

    "http://pv.sohu.com/cityjson",
    "http://pv.sohu.com/cityjson?ie=utf-8",
    "http://ip.chinaz.com/getip.aspx",
 

    Android Java代码参考如下:

 1.获取公网IP

String[] platforms = {
        "http://pv.sohu.com/cityjson",
        "http://pv.sohu.com/cityjson?ie=utf-8",
        "http://ip.chinaz.com/getip.aspx",
};
private String getOutNetIP(Context context, int index) { if (index < platforms.length) { BufferedReader buff = null; HttpURLConnection urlConnection = null; try { URL url = new URL(platforms[index]); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.setReadTimeout(5000);//读取超时 urlConnection.setConnectTimeout(5000);//连接超时 urlConnection.setDoInput(true); urlConnection.setUseCaches(false); int responseCode = urlConnection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) {//找到服务器的情况下,可能还会找到别的网站返回html格式的数据 InputStream is = urlConnection.getInputStream(); buff = new BufferedReader(new InputStreamReader(is, "UTF-8"));//注意编码,会出现乱码 StringBuilder builder = new StringBuilder(); String line = null; while ((line = buff.readLine()) != null) { PlatformLogUtil.at(TAG, "line : " + line); builder.append(line); } buff.close();//内部会关闭 InputStream urlConnection.disconnect(); Log.e(TAG, builder.toString()); if (index == 0 || index == 1) { //截取字符串 int satrtIndex = builder.indexOf("{");//包含[ int endIndex = builder.indexOf("}");//包含] String json = builder.substring(satrtIndex, endIndex + 1);//包含[satrtIndex,endIndex) JSONObject jo = new JSONObject(json); String ip = jo.getString("cip"); return ip; } else if (index == 2) { JSONObject jo = new JSONObject(builder.toString()); return jo.getString("ip"); } } } catch (Exception e) { e.printStackTrace(); } } return getOutNetIP(context, ++index); } 

 2.Linux下通过 curl 指令可以直接网址获取公网IP信息

curl icanhazip.com
curl http://pv.sohu.com/cityjson?ie=utf-8

 

 

三、通过ip2region(IP地址定位库)进行查询

  ip2region是第三方准确率99.9%的离线库,体积小只有几MB,在国内可以准确定位到城市及运营商信息,通过客制化存放到系统目录,如"/data/system/ip2region.db"

  ip2region.db 已上传到百度:

  链接:https://pan.baidu.com/s/1sO9zcjJTzrvvFILquPLzzQ
  提取码:lqed

   /**
     * 解析Ip地址工具类,传入IP地址,返回省、市、城市、运行商,以\t分割
     */
    private String parseIP(String ip) {
        String result = "";
        // 关联下载的id2region.db 离线库
        String dbFile = "/data/system/ip2region.db";
        try {
            DbSearcher search = new DbSearcher(new DbConfig(), dbFile);
            // 传入ip进行解析
            DataBlock dataBlock = search.btreeSearch(ip);
            // 获取解析后的数据  
            
            String region = dataBlock.getRegion();
            Log.d(TAG, "region : " + region);
            String replace = region.replace("|", ",");
            String[] splits = replace.split(",");
            if (splits.length == 5) {
                String country = splits[0];
                String province = splits[2];
                String city = splits[3];
                String operator = splits[4];
                // 拼接数据
                result = country + "\t" + province + "\t" + city + "\t" + operator;
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

  Ip2region项目详细参考https://gitee.com/lionsoul/ip2region

  注:Android 4.0 之后不能在主线程中请求HTTP请求,需要放到子线程中:
    try {
        new Thread(new Runnable(){
            @Override
            public void run() {
                String curIp = getOutNetIP(mContext,1);
                String region = parseIP(curIp);
                Log.d(TAG, "IP :" + curIp + " | 地区: " + region);
                Toast.makeText(mContext, "IP :" + curIp +" | 地区: " + region, Toast.LENGTH_SHORT).show();
            }
        }).start();
    } catch (RemoteException e) {
        e.printStackTrace();
    }

  获取结果如下:

 

  定位城市后可以通过主要城市对照列表进行时区转换和设定。

 

posted on 2020-09-07 17:08  sheldon_blogs  阅读(921)  评论(0编辑  收藏  举报

导航