Android基站定位源代码

本文详细介绍了如何在Android设备上实现联通、移动、电信等不同运营商的基站定位,并提供了具体的代码实现,包括通过Google Gears获取GPS经纬度以及利用Google Map API获取当前位置。

摘要生成于 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  int NETWORK_TYPE_UNKNOWN  =  0 ;
/** Current network is GPRS */
public  static  final  int NETWORK_TYPE_GPRS  =  1 ;
/** Current network is EDGE */
public  static  final  int NETWORK_TYPE_EDGE  =  2 ;
/** Current network is UMTS */
public  static  final  int NETWORK_TYPE_UMTS  =  3 ;
/** Current network is CDMA: Either IS95A or IS95B*/
public  static  final  int NETWORK_TYPE_CDMA  =  4 ;
/** Current network is EVDO revision 0*/
public  static  final  int NETWORK_TYPE_EVDO_0  =  5 ;
/** Current network is EVDO revision A*/
public  static  final  int NETWORK_TYPE_EVDO_A  =  6 ;
/** Current network is 1xRTT*/
public  static  final  int NETWORK_TYPE_1xRTT  =  7 ;
/** Current network is HSDPA */
public  static  final  int NETWORK_TYPE_HSDPA  =  8 ;
/** Current network is HSUPA */
public  static  final  int NETWORK_TYPE_HSUPA  =  9 ;
/** Current network is HSPA */
public  static  final  int NETWORK_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 ) ;
int type  = 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
private Location callGear ( ArrayList cellID )  {
if  (cellID  ==  null )  return  null ;
DefaultHttpClient client  =  new DefaultHttpClient ( ) ;
HttpPost post  =  new HttpPost (
"http://www.google.com/loc/json" ) ;
JSONObject holder  =  new JSONObject ( ) ;
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  =  new JSONArray ( ) ;
current_data  =  new JSONObject ( ) ;
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  ( int i  =  1 ; i  &lt ; cellID. size ( ) ; i ++ )  {
data  =  new JSONObject ( ) ;
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  =  new StringEntity (holder. toString ( ) ) ;
Log. e ( "Location send", holder. toString ( ) ) ;
post. setEntity (se ) ;
HttpResponse resp  = client. execute (post ) ;
HttpEntity entity  = resp. getEntity ( ) ;

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

Location loc  =  new Location (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 ( ) ) ;
return loc ;
}  catch  (JSONException e )  {
return  null ;
}  catch  ( UnsupportedEncodingException e )  {
e. printStackTrace ( ) ;
}  catch  (ClientProtocolException e )  {
e. printStackTrace ( ) ;
}  catch  ( IOException e )  {
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  String getLocation (Location itude )  throws  Exception  {
String resultString  =  "" ;

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

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

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

return resultString ;
}

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-

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值