概述
Google Maps Geolocation API的官方文档在这里:https://developers.google.com/maps/documentation/business/geolocation/?hl=zh-CN
我们可以申请测试key,链接在此:https://code.google.com/apis/console/?noredirect,免费配额是100次API请求/每天,申请前必须新建一个project,并且完善信用卡支付信息。
我一开始没有填写信用卡,导致尝试了各种请求都是失败,报错为:Geolocation API Daily Limit Exceeded,后来重新生成了API key再请求就OK了。
一般而言,服务器返回403 Forbidden表示key有问题或者referer不在允许的列表里;400 Bad Request表示请求的json参数有问题;404 Not Found可能表示要查找的经纬度信息不存在,应该是请求的json参数中的数值有问题。
根据Geolocation API的要求,对于电信CDMA2000制式的手机,查询经纬度主要需要如下信息:
MobileCountryCode(MCC)+MobileNetworkCode(MNC)+cellId+locationAreaCode
MobileCountryCode和MobileNetworkCode的说明在这里:http://en.wikipedia.org/wiki/List_of_mobile_country_codes
cellId在CDMA2000中代表Base Station ID (BID)
locationAreaCode在CDMA2000中代表Network ID (NID)
radioType在CDMA2000中取值cdma
API请求的参数为json格式,示例如下:
{
"homeMobileCountryCode": 460,
"homeMobileNetworkCode": 14174,
"radioType": "cdma",
"cellTowers": [
{
"cellId": 585,
"locationAreaCode": 10,
"mobileCountryCode": 460,
"mobileNetworkCode": 14174
}
]
}
官方示例中使用cURL测试接口和key,命令为:
curl -d @georeqct.json -H "Content-Type: application/json" -i "https://www.googleapis.com/geolocation/v1/geolocate?key=yourkey"
返回数据也是json格式,示例如下:
{
"location": {
"lat": 32.1105539,
"lng": 118.92446569999998
},
"accuracy": 1604.0
}
上面的返回值分别代表经纬度以及精确度。
下面贴一下Android中获取请求参数的代码:
package org.bigroom.celltowerinfo;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends Activity {
static final private int MENU_Exit = Menu.FIRST;
static final private int MENU_CellIdInfo = Menu.FIRST+1;
TelephonyManager tm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, MENU_Exit, 0, "Exit");
menu.add(0, MENU_CellIdInfo, 1, "MENU_CellIdInfo");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case (MENU_Exit):
MainActivity.this.finish();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
break;
case (MENU_CellIdInfo):
CdmaCellLocation ccl = (CdmaCellLocation) tm.getCellLocation();
int BSId=ccl.getBaseStationId();
int BSSLat = ccl.getBaseStationLatitude();
int BSSLon = ccl.getBaseStationLongitude();
int Nid=ccl.getNetworkId();
int Sid=ccl.getSystemId();
int mcc = Integer.valueOf(tm.getNetworkOperator().substring(0, 3));
int mnc = Integer.valueOf(tm.getNetworkOperator().substring(3, 5));
String CellIdInfo="BSId:"+String.valueOf(BSId)+" "+"BSSLat:"+String.valueOf(BSSLat)+" "+"BSSLon:"+String.valueOf(BSSLon)+" "+"Nid:"+String.valueOf(Nid)+" "+"Sid:"+String.valueOf(Sid)+" "+"mcc:"+String.valueOf(mcc)+" "+"mnc:"+String.valueOf(mnc);
Log.d("debug", CellIdInfo);
Toast.makeText(getApplicationContext(), CellIdInfo, Toast.LENGTH_LONG).show();
break;
}
return super.onOptionsItemSelected(item);
}
}
要注意在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
对于CDMA网络,其实可以直接从SDK中获取经纬度。。。
使用我的手机获取到的数据为:
BSId:585 BSSLat:462444 BSSLon:1712572 Nid:10 Sid:14174 mcc:460 mnc:3
这里的经纬度值的定义在这里:
Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf) It is represented in units of 0.25 seconds and ranges from -1296000 to 1296000, both values inclusive (corresponding to a range of -90 to +90 degrees).
Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf) It is represented in units of 0.25 seconds and ranges from -2592000 to 2592000, both values inclusive (corresponding to a range of -180 to +180 degrees).
根据换算关系可以算出SDK中获取的Longitude为1712572/14400=118.93,Latitude为462444/14400=32.11,通过查找地图发现这一对数值能够正确标识我的实际位置。
回到Geolocation API,除了新建json文本使用cURL模拟Server提交测试之外,我们还可以使用Python模拟Brower测试,代码为:
import json
import urllib2
cellTowersData={'cellId':585,'locationAreaCode':10,'mobileCountryCode':460,'mobileNetworkCode':14174}
geoLocationRequestData = {'radioType':'cdma','cellTowers':[cellTowersData]}
geoLocationRequestJsonData = json.dumps(geoLocationRequestData)
geoLocationRequestUrl = "https://www.googleapis.com/geolocation/v1/geolocate?key=yourkey"
geoLocationRequest = urllib2.Request(geoLocationRequestUrl, geoLocationRequestJsonData, {'Content-Type': 'application/json','Referer': '*.chenxupro.com/*'})
try:
geoLocationResponse = urllib2.urlopen(geoLocationRequest)
geoLocationResponseContent = geoLocationResponse.read()
print geoLocationResponseContent
geoLocationResponse.close()
except (urllib2.HTTPError,),e:
print "Load Error,%s" % e
测试结果截图如下:
上图中获取的Lat值和Lon值和SDK里获取的值还是比较接近的。
Google还提供了丰富的Report功能,便于开发者查看API请求情况,示例如下:
最后
以上就是伶俐电话为你收集整理的电信Android手机结合Google Maps Geolocation API定位的全部内容,希望文章能够帮你解决电信Android手机结合Google Maps Geolocation API定位所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复