微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 手机设计讨论 > MTK手机平台交流 > 如何通过网络确定当前时区-1

如何通过网络确定当前时区-1

时间:10-02 整理:3721RD 点击:
[DESCRIPTION]

android本身在自动确定时间&时区方面做的不够好,有的客户对这方面要求比较高,这就需要通过其他方式来做。
这份文档是对于没有NITZ的情况下,添加自动确定时区的功能。

[SOLUTION]

如何通过网络确定当前时区
1 判断目前网络状况
1.1 定位条件比较
需要根据目前的网络条件决定使用何种方式来定位,下面是三种定位方式的使用条件:
1. wifi ip定位条件:wifi连接到网络,能够正常访问互联网;
2. 基站定位:正常注册到运营商网络,能够正常访问互联网;
3. WPS定位:wifi打开,可以搜索到有效wifi信号,能够正常访问互联网;
1.2 定位方式比较
这三种方式都需要能够正常访问互联网,因为这些查询数据库在网络服务器中,
第一种方式不需要插卡即可定位,但是偏差较大,如果使用代理可能会定位错误;
第二种方式可以使用GPRS数据连接访问互联网,数据量较小,但是http请求延时较大;
第三种方式是一种最新的定位技术,定位精准,但需要wifi信号在数据库中有记录;
1.3 使用合适的定位方式
由于本文档的目的是为了定位到正确的时区,所以对定位的精度要求不高,获取下面两个值即可:
1. 国家
2. 经纬度
从确定时区的角度来看,使用基站定位是最符合条件的,所以基站定位应该作为首选;另外,在没有插SIM卡、或获取不到运营商网络时,通过WIFI IP定位是合适的;第三种方案是最新的定位技术,可作为备用定位方案使用。
if(isNetworkAvailable){ //判断是否可以访问网络
if(canGetCellInfo){ //如果可以获取到基站信息
getLocationByCellinfo(); //使用基站信息获取目前位置信息
}
else if(canGetWifiIpAddress){ //如果基站信息不能获取到,
getLocationByIpAddress(); //通过IP地址定位
}
else
getLocationByWps(); //如果前面两张方法都不能用,使用WPS定位
}
2 获取当前位置信息
2.1 Wifi IP地址定位
这种方式是通过wifi连接到互联网之后,通过访问指定的服务器,然后该网站会返回你的ip地址及相关信息,主要步
骤为:获取外网IP信息 ->(根据IP查询位置信息)->解析返回数据。
2.1.1 (推荐)方法1:直接获取当前IP地理信息
请求数据:
http://j.maxmind.com/app/geoip.js
返回数据:
function geoip_country_code() { return 'CN'; }
function geoip_country_name() { return 'China'; }
function geoip_city() { return 'Shenzhen'; }
function geoip_region() { return '30'; }
function geoip_region_name() { return 'Guangdong'; }
function geoip_latitude() { return '22.5333'; }
function geoip_longitude() { return '114.1333'; }
function geoip_postal_code() { return ''; }
function geoip_area_code() { return ''; }
function geoip_metro_code() { return ''; }
解析数据
通过字符串分解或正则表达式匹配得到下面几个函数的返回值:
geoip_country_code
geoip_latitude
geoip_longitude
2.1.2 方法2:查询指定IP信息
1) 获取外网IP
通过Android的wifi service获取的是内网的IP,无法在IP数据库中进行查询,所以应该获取外网IP。
获取外网IP的方法是:访问网络中有独立IP的服务器,使用该服务器返回的访问IP;
提供该接口的网站:http://www.ip138.com/
请求数据:
http://iframe.ip138.com/ic.asp
返回数据:
数据格式:text
数据内容实例:您的IP是:[119.145.0.123] 来自:广东省深圳市 电信
2) 查询IP位置信息
查询IP数据库,获取该IP地址的详细信息。
有多家网站提供免费查询,经过比较这个比较准确:http://ipinfodb.com/
请求数据:
http://api.ipinfodb.com/v3/ip-city/?key={key}&ip={ip}
参数{key}:通过在该网站注册获取的key
参数{ip}:需要查询的IP地址,也就是上一步获取到的手机外网IP
返回数据:
数据格式:JSON
数据内容实例:OK;;119.145.0.123;CN;CHINA;GUANGDONG;GUANGZHOU;-
;23.1167;113.25;+08:00
3) 解析返回信息(JSON)
使用split方法即可解析,分隔符为分号。下面是关于解析后的数据各位的说明:
// 0:stateCode, 1:unknow, 2:ip address, 3:ISO ,4:country name
// 5:province name ,6:city name ,7:unknow ,8:lat ,9:lon ,10:time zone by
GMT
有用的数据:0,3,6,8,9
2.2 基站信息定位
2.2.1 获取基站信息
所需的基站信息包括:mcc、mnc、lac、cellid;
在GSMServiceStateTracker中,可以使用成员变量newSS直接得到这些信息;
在Activity中可以通过TelephonyManager获取phone相关的基站信息,如下面代码所示:
TelephonyManager mTelephonyManager = (TelephonyManager)
getSystEMService(Context.TELEPHONY_SERVICE);
CellInfo cellInfo = new CellInfo();
// 返回值MCC + MNC
String operator = mTelephonyManager.getNetworkOperator();
cellInfo.mcc = Integer.parseInt(operator.substring(0, 3));
cellInfo.mnc = Integer.parseInt(operator.substring(3));
// 中国移动和中国联通获取LAC、CID的方式
GsmCellLocation location = (GsmCellLocation)
mTelephonyManager.getCellLocation();
cellInfo.lac = location.getLac();
cellInfo.cellid = location.getCid();
2.2.2 查询基站位置信息
查询基站信息数据库,获取该基站详细信息,根据该基站可以基本确定手机位置;
有多家网站提供免费查询,经过比较这个比较准确:http://www.opencellid.org/
请求数据:
http://www.opencellid.org/cell/get?key={key}&mcc={mcc}
&mnc={mnc}&lac={lac}&cellid={cellid}
参数{key}:通过在该网站注册获取的key
参数{ mcc }:Mobile Country Code,移动国家号码
参数{ mnc }:Mobile Network Code,移动网络号码
参数{ lac }:Location Area Code位置区码,如果没有可以为0;
参数{ cellid }:小区索引,如果没有可以为0;
返回数据:
数据格式:XML
数据内容实例:
<?xml version="1.0" encoding="UTF-8" ?>
<rsp stat="ok">
<cell lac="0" mcc="460" lat="26.0812621636364" lon="116.673558672727"
cellId="0" nbSamples="22" mnc="0" range="6000" />
</rsp>
2.2.3 解析返回信息(XML)
由于返回的数据内容简单,可以采用xml解析器解析或使用正则表达式匹配;
比如在Java中匹配lat属性的浮点数的RegString:”(?<=lat=\\\")[\\d\\.]+” ;
这里解析出有用的数据较少,只有lat和lon。
2.2.4 获取ISO信息
由于上一步中获取的信息没有country code信息,但是比较查询的时候可能会用到,所以这里还是要通过mcc信
息获取到具体的iso代码;
在GSMServiceStateTracker中,可以调用MccTable的静态方法countryCodeForMcc(mcc)获取
iso;
在Activity中,需要自己建立iso与mcc的映射关系,然后进行查询;
2.3 WPS定位
2.3.1 调用Skyhook WPS定位API
XPS _xps = new XPS(context);
WPSAuthentication auth = new WPSAuthentication("quwanxin", "mtk");
_xps.setRegistrationUser(auth);
_xps.getLocation(null, WPSStreetAddressLookup.WPS_NO_STREET_ADDRESS_LOOKUP
,callback);
2.3.2 编写callback处理返回信息
private WPSLocationCallback callback = new WPSLocationCallback()
需要重写的方法包括:
public void done() //定位事件完成后要做的事情
public WPSContinuation handleError(WPSReturnCode error) //发生错误时的处理
public void handleWPSLocation(WPSLocation location) //正确定位后对于位置信息的处理

未完-待续

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top