我是靠谱客的博主 伶俐电话,最近开发中收集的这篇文章主要介绍电信Android手机结合Google Maps Geolocation API定位,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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定位所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(74)

评论列表共有 0 条评论

立即
投稿
返回
顶部