【Android开发笔记】由微信定位想到的Android基站定位源代码

导读:经过几天的调研以及测试,终于解决了联通2G、移动2G、电信3G的基站定位代码。团队里面只有这些机器的制式了。下面就由我来做一个详细的讲解吧。

  经过几天的调研以及测试,终于解决了联通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();
03   //中国电信为CTC
04   //NETWORK_TYPE_EVDO_A是中国电信3G的getNetworkType
05   //NETWORK_TYPE_CDMA电信2G是CDMA
06    if (type == TelephonyManager.NETWORK_TYPE_EVDO_A || type == TelephonyManager.NETWORK_TYPE_CDMA || type ==TelephonyManager.NETWORK_TYPE_1xRTT)
07   {
08   }
09   //移动2G卡 + CMCC + 2
10   //type = NETWORK_TYPE_EDGE
11   else if(type == TelephonyManager.NETWORK_TYPE_EDGE)
12   {
13   }
14   //联通的2G经过测试 China Unicom 1 NETWORK_TYPE_GPRS
15   else if(type == TelephonyManager.NETWORK_TYPE_GPRS)
16   {
17   }
18   else
19   {
20   tv.setText("Current Not Support This Type.");
21   }
3 通过基站的基本信息,通过Google Gears获取对应的GPS经纬度。这部分前面的两篇文章都有提到,代码参考了网友们的代码,感谢感谢。
01   private Location callGear(ArrayList cellID) {
02   if (cellID == nullreturn null
03   DefaultHttpClient client = new DefaultHttpClient();
04   HttpPost post = new HttpPost(
05   "http://www.google.com/loc/json");
06   JSONObject holder = new JSONObject();
07   try {
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");
16   else
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);
34   data.put("age"0);
35   array.put(data);
36   }
37   }
38   holder.put("cell_towers", array);
39   StringEntity se = new StringEntity(holder.toString());
40   Log.e("Location send", holder.toString());
41   post.setEntity(se);
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);
50   sb.append(result);
51   result = br.readLine();
52   }
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());
61   return loc;
62   } catch (JSONException e) {
63   return null
64   } catch (UnsupportedEncodingException e) {
65   e.printStackTrace();
66   } catch (ClientProtocolException e) {
67   e.printStackTrace();
68   } catch (IOException e) {
69   e.printStackTrace();
70   }
71   return null
72   }

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

01   private String getLocation(Location itude) throws Exception {
02   String resultString = ""
03   /** 这里采用get方法,直接将参数加到URL上 */
04   String urlString = String.format("http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s", itude .getLatitude(), itude.getLongitude());
05   Log.i("URL", urlString);
06   /** 新建HttpClient */
07   HttpClient client = new DefaultHttpClient();
08   /** 采用GET方法 */
09   HttpGet get = new HttpGet(urlString);
10   try {
11   /** 发起GET请求并获得返回数据 */
12   HttpResponse response = client.execute(get);
13   HttpEntity entity = response.getEntity();
14   BufferedReader buffReader = new BufferedReader(new InputStreamReader(entity.getContent()));
15   StringBuffer strBuff = new StringBuffer();
16   String result = null
17   while ((result = buffReader.readLine()) != null) {
18   strBuff.append(result);
19   }
20   resultString = strBuff.toString();
21   /** 解析JSON数据,获得物理地址 */
22   if (resultString != null && resultString.length() > 0) {
23   JSONObject jsonobject = new JSONObject(resultString);
24   JSONArray jsonArray = new JSONArray(jsonobject.get("Placemark").toString());
25   resultString = ""
26   for int i = 0; i < jsonArray.length(); i++) {
27   resultString = jsonArray.getJSONObject(i).getString("address");
28   }
29   }
30   } catch (Exception e) {
31   throw new Exception("获取物理位置出现错误:" + e.getMessage());
32   } finally {
33   get.abort();
34   client = null
35   }
36   return resultString;
37   }



  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”}

公司地址:广州市番禺区亚运东路56号602室 电话:18929558018传真:020-84647115
版权所有:深圳市翡之翠文化传播有限公司 客户邮箱:h91708@163.COM

©2012 粤ICP备12043775号


技术支持:趋向互动
分享按钮