经过几天的调研以及测试,终于解决了联通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的管理。 TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 通过这个方式就可以得到TelephonyManager接口。 这个接口的源代码可以通过设置在项目里面查看,这里不具体附上了。 得到TelephonyManager后,由于针对不同的运营商,代码有所不同,所以需要判断getNetworkType() 在源代码里面有如下的类型定义
01 |
/** Network type is unknown */ |
02 |
public static final int NETWORK_TYPE_UNKNOWN = 0 ; |
03 |
/** Current network is GPRS */ |
04 |
public static final int NETWORK_TYPE_GPRS = 1 ; |
05 |
/** Current network is EDGE */ |
06 |
public static final int NETWORK_TYPE_EDGE = 2 ; |
07 |
/** Current network is UMTS */ |
08 |
public static final int NETWORK_TYPE_UMTS = 3 ; |
09 |
/** Current network is CDMA: Either IS95A or IS95B*/ |
10 |
public static final int NETWORK_TYPE_CDMA = 4 ; |
11 |
/** Current network is EVDO revision 0*/ |
12 |
public static final int NETWORK_TYPE_EVDO_0 = 5 ; |
13 |
/** Current network is EVDO revision A*/ |
14 |
public static final int NETWORK_TYPE_EVDO_A = 6 ; |
15 |
/** Current network is 1xRTT*/ |
16 |
public static final int NETWORK_TYPE_1xRTT = 7 ; |
17 |
/** Current network is HSDPA */ |
18 |
public static final int NETWORK_TYPE_HSDPA = 8 ; |
19 |
/** Current network is HSUPA */ |
20 |
public static final int NETWORK_TYPE_HSUPA = 9 ; |
21 |
/** Current network is HSPA */ |
22 |
public static final int NETWORK_TYPE_HSPA = 10 ;\ |
2 联通、移动、电信不同制式在获取基站位置的代码区别。 这部分是我实际测试出来的,经过无数次的拆机,放卡,才实现了不同制式的完美实现。 代码如下:
01 |
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); |
02 |
int type = tm.getNetworkType(); |
06 |
if (type == TelephonyManager.NETWORK_TYPE_EVDO_A || type == TelephonyManager.NETWORK_TYPE_CDMA || type ==TelephonyManager.NETWORK_TYPE_1xRTT) |
11 |
else if (type == TelephonyManager.NETWORK_TYPE_EDGE) |
15 |
else if (type == TelephonyManager.NETWORK_TYPE_GPRS) |
20 |
tv.setText( "Current Not Support This Type." ); |
3 通过基站的基本信息,通过Google Gears获取对应的GPS经纬度。这部分前面的两篇文章都有提到,代码参考了网友们的代码,感谢感谢。
01 |
private Location callGear(ArrayList cellID) { |
02 |
if (cellID == null ) return null ; |
03 |
DefaultHttpClient client = new DefaultHttpClient(); |
04 |
HttpPost post = new HttpPost( |
05 |
"http://www.google.com/loc/json" ); |
06 |
JSONObject holder = new JSONObject(); |
08 |
holder.put( "version" , "1.1.0" ); |
09 |
holder.put( "host" , "maps.google.com" ); |
10 |
holder.put( "home_mobile_country_code" , cellID.get( 0 ).mobileCountryCode); |
11 |
holder.put( "home_mobile_network_code" , cellID.get( 0 ).mobileNetworkCode); |
12 |
holder.put( "radio_type" , cellID.get( 0 ).radioType); |
13 |
holder.put( "request_address" , true ); |
14 |
if ( "460" .equals(cellID.get( 0 ).mobileCountryCode)) |
15 |
holder.put( "address_language" , "zh_CN" ); |
17 |
holder.put( "address_language" , "en_US" ); |
18 |
JSONObject data,current_data; |
19 |
JSONArray array = new JSONArray(); |
20 |
current_data = new JSONObject(); |
21 |
current_data.put( "cell_id" , cellID.get( 0 ).cellId); |
22 |
current_data.put( "location_area_code" , cellID.get( 0 ).locationAreaCode); |
23 |
current_data.put( "mobile_country_code" , cellID.get( 0 ).mobileCountryCode); |
24 |
current_data.put( "mobile_network_code" , cellID.get( 0 ).mobileNetworkCode); |
25 |
current_data.put( "age" , 0 ); |
26 |
array.put(current_data); |
27 |
if (cellID.size() > 2 ) { |
28 |
for ( int i = 1 ; i < cellID.size(); i++) { |
29 |
data = new JSONObject(); |
30 |
data.put( "cell_id" , cellID.get(i).cellId); |
31 |
data.put( "location_area_code" , cellID.get(i).locationAreaCode); |
32 |
data.put( "mobile_country_code" , cellID.get(i).mobileCountryCode); |
33 |
data.put( "mobile_network_code" , cellID.get(i).mobileNetworkCode); |
38 |
holder.put( "cell_towers" , array); |
39 |
StringEntity se = new StringEntity(holder.toString()); |
40 |
Log.e( "Location send" , holder.toString()); |
42 |
HttpResponse resp = client.execute(post); |
43 |
HttpEntity entity = resp.getEntity(); |
44 |
BufferedReader br = new BufferedReader( |
45 |
new InputStreamReader(entity.getContent())); |
46 |
StringBuffer sb = new StringBuffer(); |
47 |
String result = br.readLine(); |
48 |
while (result != null ) { |
49 |
Log.e( "Locaiton receive" , result); |
51 |
result = br.readLine(); |
53 |
if (sb.length() return null ; |
54 |
data = new JSONObject(sb.toString()); |
55 |
data = (JSONObject) data.get( "location" ); |
56 |
Location loc = new Location(LocationManager.NETWORK_PROVIDER); |
57 |
loc.setLatitude((Double) data.get( "latitude" )); |
58 |
loc.setLongitude((Double) data.get( "longitude" )); |
59 |
loc.setAccuracy(Float.parseFloat(data.get( "accuracy" ).toString())); |
60 |
loc.setTime(GetUTCTime()); |
62 |
} catch (JSONException e) { |
64 |
} catch (UnsupportedEncodingException e) { |
66 |
} catch (ClientProtocolException e) { |
68 |
} catch (IOException e) { |