• 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地址,返回省、市、城市、运行商,以	分割
         */
        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 + "	" + province + "	" + city + "	" + 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();
        }

      获取结果如下:

     

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

  • 相关阅读:
    EF-一对一关系
    EF-生成迁移版本
    打包、压缩指令
    gut pull 拉取出错
    nohup的使用方法
    fopen打开文件出错
    实现多线程下载图片到本地③
    实现单线程下载图片到本地②
    服务器重装系统后终端登录不上去
    简单实现图片抓取下载到本地①
  • 原文地址:https://www.cnblogs.com/blogs-of-lxl/p/13627924.html
Copyright © 2020-2023  润新知