最近发现用Android上自带的定位接口在很多机型上都无法通过基站进行定位,使用Geolocation定位接口就能解决这样的问题。
android手机网络复杂,有移动2G的GSM网,有联通3G的WCDMA,还有电信定制机采用的CDMA2000,甚至还有不插SIM卡直接用WIFI的。我们要在所有这些不同的网络环境下进行定位,除了室外才能用的GPS,android自带的基站定位接口是不能完全满足要求的。测试表明,Google提供的GeoLocation接口能支持GSM/WCDMA/CDMA/WIFI室内定位。
具体使用:
接口:Google GeolocationAPI 是google的综合定位接口。基站定位,Wi-Fi定位,GPS定位都可以通过gears GeolocationAPI来查询。GeolocationAPI google有官方的详细api说明。GeolocationAPI接口使用HTTP协议,交互数据为json语法。
1. 发送数据
向Google服务器请求的数据格式如下:
{ "version": "1.1.0", "host": "maps.google.com", "access_token": "2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe", "home_mobile_country_code": 310, "home_mobile_network_code": 410, "radio_type": "gsm", "carrier": "Vodafone", "request_address": true, "address_language": "en_GB", "location": { "latitude": 51.0, "longitude": -0.1 }, "cell_towers": [ { "cell_id": 42, "location_area_code": 415, "mobile_country_code": 310, "mobile_network_code": 410, "age": 0, "signal_strength": -60, "timing_advance": 5555 }, { "cell_id": 88, "location_area_code": 415, "mobile_country_code": 310, "mobile_network_code": 580, "age": 0, "signal_strength": -70, "timing_advance": 7777 } ], "wifi_towers": [ { "mac_address": "01-23-45-67-89-ab", "signal_strength": 8, "age": 0 }, { "mac_address": "01-23-45-67-89-ac", "signal_strength": 4, "age": 0 } ] }
其中,radio_type通过TelephonyManager.getNetworkType()获取;signal_strength在PhoneStateListener的回调方法onSignalStrengthChanged中可以得到,mobile_country_code:取telephonyManager.getSimOperator()的前3位数字。剩下的cell_id、location_area_code和mobile_network_code根据网络类型不同而不同:
GSM
cell_id: gsmCellLocation.getCid()
location_area_code:gsmCellLocation.getLac()
mobile_network_code:telephonyManager.getSimOperator()第4位以后的数字
CDMA
cell_id 用 BID值替换 cdmaCellLocation.getBaseStationId()
location_area_code 用NID值替换 cdmaCellLocation.getNetworkId()
mobile_network_code用SID值替换 cdmaCellLocation.getSystemId()
WIFI数据可以通过ScanResult获取:
mac_address: scanResult.BSSID
signal_strength: scanResult.level
ssid: scanResult.SSID
通过Android平台上的相关接口获取到这些数据之后可以用JSONString组织JSON串:
js. object ( ) ;
js. key ( "version" ). value ( "1.1.0" ) ;
js. key ( "host" ). value ( "maps.google.com" ) ;
js. key ( "request_address" ). value ( true ) ;
js. key ( "address_language" ). value ( "zh_CN" ) ;
if (mRadioData != null & ;& ; !mRadioData. radioType. equals (RadioDataProvider. RADIO_TYPE_UNKNOWN ) ) {
js. key ( "home_mobile_country_code" ). value (mRadioData. homeMobileCountryCode ) ;
js. key ( "home_mobile_network_code" ). value (mRadioData. homeMobileNetworkCode ) ;
js. key ( "radio_type" ). value (mRadioData. radioType ) ;
js. key ( "carrier" ). value (mRadioData. carrierName ) ;
//cell_towers
JSONObject cell_towers = new JSONObject ( ) ;
cell_towers. put ( "cell_id", mRadioData. cellId ) ;
cell_towers. put ( "location_area_code", mRadioData. locationAreaCode ) ;
cell_towers. put ( "mobile_country_code", mRadioData. mobileCountryCode ) ;
cell_towers. put ( "mobile_network_code", mRadioData. mobileNetworkCode ) ;
cell_towers. put ( "age", 0 ) ;
cell_towers. put ( "signal_strength", mRadioData. signalStrength ) ;
js. key ( "cell_towers" ). value ( new JSONArray ( ). put (cell_towers ) ) ;
}
// wifi_towers
if (mScanResults != null & ;& ; mScanResults. size ( ) > ; 0 ) {
ScanResult result = mScanResults. get ( 0 ) ;
JSONObject wifi_towers = new JSONObject ( ) ;
wifi_towers. put ( "mac_address", result. BSSID ) ;
wifi_towers. put ( "signal_strength", result. level ) ;
wifi_towers. put ( "age", 0 ) ;
wifi_towers. put ( "ssid", result. SSID ) ;
js. key ( "wifi_towers" ). value ( new JSONArray ( ). put (wifi_towers ) ) ;
}
js. endObject ( ) ;
将这样的JSON数据发送到 http://www.google.com/loc/json ,然后等待返回结果。
2. 接收数据
Google服务器返回的数据格式如下:
{ "location": { "latitude": 51.0, "longitude": -0.1, "altitude": 30.1, "accuracy": 1200.4, "altitude_accuracy": 10.6, "address": { "street_number": "100", "street": "Amphibian Walkway", "postal_code": "94043", "city": "Mountain View", "county": "Mountain View County", "region": "California", "country": "United States of America", "country_code": "US" } }, "access_token": "2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe" }
使用JSONObject可以很方便的解析出需要的经纬度和地址信息了。