Android基站定位源代码

本文详细阐述了如何使用GoogleAndroidAPI实现联通、移动、电信的基站定位代码,并解决了GPS经纬度显示偏移等问题。包括TelephonyManager管理、不同运营商代码区别、GPS经纬度获取与转换、GoogleMapAPI应用等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.jouhu.com/blog/?p=1937

经过几天的调研以及测试,终于解决了联通2G、移动2G、电信3G的基站定位代码。团队里面只有这些机器的制式了。下面就由我来做一个详细的讲解吧。
1 相关技术内容
Google Android Api里面的TelephonyManager的管理。
联通、移动、电信不同制式在获取基站位置的代码区别。
通过基站的基本信息,通过Google Gears获取对应的GPS经纬度。
通过Google Map API根据GPS经纬度获取当前位置。

2 目前存在的几个问题
由于得到的GPS经纬度在Google Map上面显示需要偏移,这块暂时没有进行处理。
没有使用PhoneStateListener来对状态实时进行更新。
没有使用线程异步获取数据
没有使用服务的方式来实时获取数据
所以如果是商业使用的话,还需进一步修改。

3 当然本部分代码已经移植到我们的家庭卫士的项目中了,2提到的问题全部解决了。

下面我针对第一部分的四大内容进行代码注解。

1 Google Android Api里面的TelephonyManager的管理。

1
TelephonyManager tm = (TelephonyManager )getSystemService ( Context. TELEPHONY_SERVICE ) ;

通过这个方式就可以得到TelephonyManager接口。
这个接口的源代码可以通过设置在项目里面查看,这里不具体附上了。
得到TelephonyManager后,由于针对不同的运营商,代码有所不同,所以需要判断getNetworkType()
在源代码里面有如下的类型定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/** Network type is unknown */
public static final intNETWORK_TYPE_UNKNOWN = 0 ;
/** Current network is GPRS */
public static final intNETWORK_TYPE_GPRS = 1 ;
/** Current network is EDGE */
public static final intNETWORK_TYPE_EDGE = 2 ;
/** Current network is UMTS */
public static final intNETWORK_TYPE_UMTS = 3 ;
/** Current network is CDMA: Either IS95A or IS95B*/
public static final intNETWORK_TYPE_CDMA = 4 ;
/** Current network is EVDO revision 0*/
public static final intNETWORK_TYPE_EVDO_0 = 5 ;
/** Current network is EVDO revision A*/
public static final intNETWORK_TYPE_EVDO_A = 6 ;
/** Current network is 1xRTT*/
public static final intNETWORK_TYPE_1xRTT = 7 ;
/** Current network is HSDPA */
public static final intNETWORK_TYPE_HSDPA = 8 ;
/** Current network is HSUPA */
public static final intNETWORK_TYPE_HSUPA = 9 ;
/** Current network is HSPA */
public static final intNETWORK_TYPE_HSPA = 10 ;

2 联通、移动、电信不同制式在获取基站位置的代码区别。

这部分是我实际测试出来的,经过无数次的拆机,放卡,才实现了不同制式的完美实现。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
TelephonyManager tm = (TelephonyManager )getSystemService ( Context. TELEPHONY_SERVICE ) ;
inttype =tm. getNetworkType ( ) ;
//中国电信为CTC
//NETWORK_TYPE_EVDO_A是中国电信3G的getNetworkType
//NETWORK_TYPE_CDMA电信2G是CDMA
if (type ==TelephonyManager. NETWORK_TYPE_EVDO_A ||type ==TelephonyManager. NETWORK_TYPE_CDMA ||type ==TelephonyManager. NETWORK_TYPE_1xRTT )
{
}
//移动2G卡 + CMCC + 2
//type = NETWORK_TYPE_EDGE
else if (type ==TelephonyManager. NETWORK_TYPE_EDGE )
{
}
//联通的2G经过测试 China Unicom 1 NETWORK_TYPE_GPRS
else if (type ==TelephonyManager. NETWORK_TYPE_GPRS )
{

}
else
{
tv. setText ( "Current Not Support This Type." ) ;
}

3 通过基站的基本信息,通过Google Gears获取对应的GPS经纬度。
这部分前面的两篇文章都有提到,代码参考了网友们的代码,感谢感谢。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
privateLocation callGear ( ArrayListcellID ) {
if (cellID == null ) return null ;
DefaultHttpClient client = newDefaultHttpClient ( ) ;
HttpPost post = newHttpPost (
"http://www.google.com/loc/json" ) ;
JSONObject holder = newJSONObject ( ) ;
try {
holder. put ( "version", "1.1.0" ) ;
holder. put ( "host", "maps.google.com" ) ;
holder. put ( "home_mobile_country_code", cellID. get ( 0 ). mobileCountryCode ) ;
holder. put ( "home_mobile_network_code", cellID. get ( 0 ). mobileNetworkCode ) ;
holder. put ( "radio_type", cellID. get ( 0 ). radioType ) ;
holder. put ( "request_address", true ) ;
if ( "460". equals (cellID. get ( 0 ). mobileCountryCode ) )
holder. put ( "address_language", "zh_CN" ) ;
else
holder. put ( "address_language", "en_US" ) ;
JSONObject data,current_data ;
JSONArray array = newJSONArray ( ) ;
current_data = newJSONObject ( ) ;
current_data. put ( "cell_id", cellID. get ( 0 ). cellId ) ;
current_data. put ( "location_area_code", cellID. get ( 0 ). locationAreaCode ) ;
current_data. put ( "mobile_country_code", cellID. get ( 0 ). mobileCountryCode ) ;
current_data. put ( "mobile_network_code", cellID. get ( 0 ). mobileNetworkCode ) ;
current_data. put ( "age", 0 ) ;
array. put (current_data ) ;
if (cellID. size ( ) &gt ; 2 ) {
for ( inti = 1 ;i &lt ;cellID. size ( ) ;i ++ ) {
data = newJSONObject ( ) ;
data. put ( "cell_id", cellID. get (i ). cellId ) ;
data. put ( "location_area_code", cellID. get (i ). locationAreaCode ) ;
data. put ( "mobile_country_code", cellID. get (i ). mobileCountryCode ) ;
data. put ( "mobile_network_code", cellID. get (i ). mobileNetworkCode ) ;
data. put ( "age", 0 ) ;
array. put (data ) ;
}
}
holder. put ( "cell_towers", array ) ;
StringEntity se = newStringEntity (holder. toString ( ) ) ;
Log. e ( "Location send", holder. toString ( ) ) ;
post. setEntity (se ) ;
HttpResponse resp =client. execute (post ) ;
HttpEntity entity =resp. getEntity ( ) ;

BufferedReaderbr = new BufferedReader (
new InputStreamReader (entity. getContent ( ) ) ) ;
StringBuffersb = new StringBuffer ( ) ;
Stringresult =br. readLine ( ) ;
while (result != null ) {
Log. e ( "Locaiton receive", result ) ;
sb. append (result ) ;
result =br. readLine ( ) ;
}
if (sb. length ( ) return null ;
data = newJSONObject (sb. toString ( ) ) ;
data = (JSONObject )data. get ( "location" ) ;

Location loc = newLocation (LocationManager. NETWORK_PROVIDER ) ;
loc. setLatitude ( ( Double )data. get ( "latitude" ) ) ;
loc. setLongitude ( ( Double )data. get ( "longitude" ) ) ;
loc. setAccuracy ( Float. parseFloat (data. get ( "accuracy" ). toString ( ) ) ) ;
loc. setTime (GetUTCTime ( ) ) ;
returnloc ;
} catch (JSONException e ) {
return null ;
} catch ( UnsupportedEncodingExceptione ) {
e. printStackTrace ( ) ;
} catch (ClientProtocolException e ) {
e. printStackTrace ( ) ;
} catch ( IOExceptione ) {
e. printStackTrace ( ) ;
}
return null ;
}

4 通过Google Map API根据GPS经纬度获取当前位置。
本部分代码参考了简单基站定位程序,感谢雷一兄这么好的文章。同时雷一兄的排版真的非常好看,清晰明了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
private StringgetLocation (Location itude ) throws Exception {
StringresultString = "" ;

/** 这里采用get方法,直接将参数加到URL上 */
StringurlString = String. format ( "http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s", itude. getLatitude ( ), itude. getLongitude ( ) ) ;
Log. i ( "URL", urlString ) ;

/** 新建HttpClient */
HttpClient client = newDefaultHttpClient ( ) ;
/** 采用GET方法 */
HttpGet get = newHttpGet (urlString ) ;
try {
/** 发起GET请求并获得返回数据 */
HttpResponse response =client. execute (get ) ;
HttpEntity entity =response. getEntity ( ) ;
BufferedReaderbuffReader = new BufferedReader ( new InputStreamReader (entity. getContent ( ) ) ) ;
StringBufferstrBuff = new StringBuffer ( ) ;
Stringresult = null ;
while ( (result =buffReader. readLine ( ) ) != null ) {
strBuff. append (result ) ;
}
resultString =strBuff. toString ( ) ;

/** 解析JSON数据,获得物理地址 */
if (resultString != null &amp ;&amp ;resultString. length ( ) &gt ; 0 ) {
JSONObject jsonobject = newJSONObject (resultString ) ;
JSONArray jsonArray = newJSONArray (jsonobject. get ( "Placemark" ). toString ( ) ) ;
resultString = "" ;
for ( inti = 0 ;i &lt ;jsonArray. length ( ) ;i ++ ) {
resultString =jsonArray. getJSONObject (i ). getString ( "address" ) ;
}
}
} catch ( Exceptione ) {
throw new Exception ( "获取物理位置出现错误:" +e. getMessage ( ) ) ;
} finally {
get. abort ( ) ;
client = null ;
}

returnresultString ;
}

5 最关键的出来了,附上代码吧。
AndroidPosition
补充一下:
在AndroidMenifest.xml里面需要加上
android.permission.INTERNET、android.permission.ACCESS_COARSE_LOCATION、android.permission.READ_PHONE_STATE权限,否则会出错。
放在Application包前面。

6 图片看一下效果吧。

7 另外在提交数据到Google Gears的时候,格式如下
发送到Google的数据格式:
02-24 18:08:20.550: E/Location send(12892): {"address_language":"zh_CN","host":"maps.google.com","radio_type":"cdma","home_mobile_country_code":"460","home_mobile_network_code":"13965","cell_towers":[{"mobile_network_code":"13965","location_area_code":11,"cell_id":1985,"age":0,"mobile_country_code":"460"}],"request_address":true,"version":"1.1.0"}

接收到Google的数据格式:
02-24 18:08:22.975: E/Locaiton receive(12892): {"location":{"latitude":43.8595097,"longitude":125.3355736,"address":{"country":"中国","country_code":"CN","region":"吉林省","city":"长春市","street":"文昌路","street_number":""},"accuracy":1815.0},"access_token":"2:_Kpk9mOFMgyWgLai:8iWlDpBYZsp4_VxO"}

-End-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值