Location in Android: Part 2

MCC(Mobile Country Code)、MNC(Mobile Network Code)、LAC(Location Aera Code)、CID(Cell Tower ID)是通讯业内的名词。MCC标识国家,MNC标识网络,两者组合起来则唯一标识一家通讯运营商。从维基百科上了解到,一个国家的MCC不唯一,例如中国有460和461,一家运营商也不只一个MNC,例如中国移动有00、02、07。LAC标识区域,类似于行政区域,运营商将大区域划分成若干小区域,每个区域分配一个LAC。CID标识基站,若手机处在工作状态,则必须要和一个通讯基站进行通讯,通过CID就可以确定手机所在的地理范围。

2006年Yahoo!曾经推出一项服务:ZoneTag,其功能之一就是拍照后将图片附上位置信息上传到Flickr。这样用户就不必对着几G,甚至几十G的图片,再费神回忆是在什么地方拍摄的了。ZoneTag也正是利用了前文中的第二种方式获得位置信息。Yahoo!后期也曾经开放ZoneTag API,这样第三方开发者就可以将MMC、MNC、LAC、CID发给Yahoo!,然后获得位置信息,但现在似乎已经关闭了接口。

Google在昔日明星Gears中提供了一项Geolocation的功能,可以获得用户的地理位置,同时这项功能也是开放的,开发者可以依照Geolocation API Network Protocol调用相关功能。稍微不令人满意的是,其数据格式为JSON(JavaScript Object Notation),没有提供XML,不够RESTful,多少是个遗憾。同时需要注意的是,由于Gears已经被Google废弃(Deprecated),因此这项功能是否会被关闭还是未知。不过,Internet上还有其他提供类似功能的服务,例如OpenCellID。

在Android当中,大部分和通讯网络相关的信息都需要经过一项系统服务,即TelephoneManager来获得。

TelephonyManager mTelMan = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String operator = mTelMan.getNetworkOperator();
String mcc = operator.substring(0, 3);
String mnc = operator.substring(3);
GsmCellLocation location = (GsmCellLocation) mTelMan.getCellLocation();
int cid = location.getCid();
int lac = location.getLac();

通过上面的方法,即可获得MCC、MNC、CID、LAC,对照Geolocation API Network Protocol,剩下不多的参数也可以获得,发起请求后根据响应内容即可得到地理位置信息。

请求(Request)的信息如下:
{"cell_towers":[{"mobile_network_code":"00","location_area_code":9733,
"mobile_country_code":"460","cell_id":17267},{"mobile_network_code":"00","location_area_code":9733,
"mobile_country_code":"460","cell_id":27852},{"mobile_network_code":"00","location_area_code":9733,
"mobile_country_code":"460","cell_id":27215},{"mobile_network_code":"00","location_area_code":9733,
"mobile_country_code":"460","cell_id":27198},{"mobile_network_code":"00","location_area_code":9484,
"mobile_country_code":"460","cell_id":27869},{"mobile_network_code":"00","location_area_code":9508,
"mobile_country_code":"460","cell_id":37297},{"mobile_network_code":"00","location_area_code":9733,
"mobile_country_code":"460","cell_id":27888}],
"host":"maps.google.com",
"version":"1.1.0"}

响应(Response)的信息如下:
{"location":{"latitude":23.12488,"longitude":113.271907,"accuracy":630.0},"
access_token":"2:61tEAW-rONCT1_W-:JVpp2_jq5a0L-5JK"}

与手机定位不同,WIFI定位主要取决于节点(node)的物理地址(mac address)。与提供TelephoneManager一样,Android也提供了获取WIFI信息的接口:WifiManager。

WifiManager wifiMan = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifiMan.getConnectionInfo();
String mac = info.getMacAddress();
String ssid = info.getSSID();

通过上面的方法,即可获得必要的请求参数。注意:根据Geolocation API Network Protocol,请求参数mac_address是指The mac address of the WiFi node,而根据WifiInfo.getMacAddress()得到的似乎是本机无线网卡地址,暂时没弄明白,留个悬疑。

暂时假定上面没有问题,发出的请求(Request)信息如下:
{"wifi_towers":[{"mac_address":"00:23:76:AC:41:5D","ssid":"Aspire-NETGEAR"}],"host":"maps.google.com","version":"1.1.0"}

响应(Response)的信息如下:
{"location":{"latitude":23.129075,"longitude":113.264423,"accuracy":140000.0},
"access_token":"2:WRr36ynOz_d9mbw5:pRErDAmJXI8l76MU"}

比较两种响应结果,发现相差较小,尽管不如GPS定位精确,但是对于通常的LBS来说,已经基本可用了。

1 Comment

[…] 原文链接:http://www.poemcode.net/2010/12/location-in-android-2/ >>> 进入[Android2D游戏开发]主题文章列表 转载编辑: Fgamers 转载地址:http://disanji.net/2011/03/11/location-in-android-part-2/ 分享到 | blog comments powered by Disqus /* […]

Leave a comment

Your comment