android GSM+CDMA基站定位

googleAPI里提供了基站信息的获取类TelephonyManager,通过其方法getCellLocation得到CellLocation即可获取到基站相关信息

CellLocation是个抽象类,所以在具体使用时需要判断接入的网络制式来用其子类CdmaCellLocationGsmCellLocation 来强转

CdmaCellLocation对应CDMA网,GsmCellLocation对应GSM

 

三大网络运营商的网络制式对应如下:

移动2G --> GSM

移动3G --> TD-SCDMA

 

电信2G --> CDMA

电信3G --> CDMA2000

 

联通2G --> GSM

联通3G --> WCDMA

 

由此可见移动,联通2G 网都可使用GsmCellLocation

电信2G,3G网则使用CdmaCellLocation

那么移动3G和联通3G又当如何

 

其实经本人亲测,移动3G网也可使用GsmCellLocation,听说是TD-SCDMA衍生于GSM,具体原因咱也不用纠结了,反正能用就是了

而联通的WCDMA据说也可使用GsmCellLocation,那姑且就是这样吧,有条件的童鞋试一试吧。

 

 

对于网络制式的判断调用TelephonyManager.getNetworkType()可有多种情况,如下:

· NETWORK_TYPE_UNKNOWN

· NETWORK_TYPE_GPRS

· NETWORK_TYPE_EDGE

· NETWORK_TYPE_UMTS

· NETWORK_TYPE_HSDPA

· NETWORK_TYPE_HSUPA

· NETWORK_TYPE_HSPA

· NETWORK_TYPE_CDMA

· NETWORK_TYPE_EVDO_0

· NETWORK_TYPE_EVDO_A

· NETWORK_TYPE_EVDO_B

· NETWORK_TYPE_1xRTT

· NETWORK_TYPE_IDEN

· NETWORK_TYPE_LTE

· NETWORK_TYPE_EHRPD

通过对网络类型判断后获取对应基站信息代码片段如下:

Html代码

1.   public static ArrayList<CellIDInfo> getCellIDInfo(Context context) throws Exception{   

2.              

3.           TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);   

4.              

5.           ArrayList<CellIDInfo> CellID = new ArrayList<CellIDInfo>();   

6.           CellIDInfo currentCell = new CellIDInfo();   

7.     

8.           int type = manager.getNetworkType();   

9.           Log.d(TAG, "getCellIDInfo-->         NetworkType = " + type);   

10.           int phoneType = manager.getPhoneType();   

11.           Log.d(TAG, "getCellIDInfo-->         phoneType = " + phoneType);   

12.              

13.           if (type == TelephonyManager.NETWORK_TYPE_GPRS              // GSM   

14.                   || type == TelephonyManager.NETWORK_TYPE_EDGE   

15.                   || type == TelephonyManager.NETWORK_TYPE_HSDPA)   

16.           {   

17.               GsmCellLocation gsm = ((GsmCellLocation) manager.getCellLocation());   

18.               if (gsm == null)   

19.               {   

20.                   Log.e(TAG, "GsmCellLocation is null!!!");   

21.                   return null;   

22.               }   

23.                      

24.     

25.               int lac = gsm.getLac();   

26.               String mcc = manager.getNetworkOperator().substring(0, 3);   

27.               String mnc = manager.getNetworkOperator().substring(3, 5);   

28.               int cid = gsm.getCid();   

29.                  

30.               currentCell.cellId = gsm.getCid();   

31.               currentCell.mobileCountryCode = mcc;   

32.               currentCell.mobileNetworkCode = mnc;   

33.               currentCell.locationAreaCode = lac;   

34.                  

35.               currentCell.radioType = "gsm";   

36.                  

37.               CellID.add(currentCell);   

38.                  

39.               // 获得邻近基站信息   

40.               List<NeighboringCellInfo> list = manager.getNeighboringCellInfo();   

41.               int size = list.size();   

42.               for (int i = 0; i < size; i++) {   

43.     

44.                   CellIDInfo info = new CellIDInfo();   

45.                   info.cellId = list.get(i).getCid();   

46.                   info.mobileCountryCode = mcc;   

47.                   info.mobileNetworkCode = mnc;   

48.                   info.locationAreaCode = lac;   

49.                  

50.                   CellID.add(info);   

51.               }   

52.                  

53.           }else if (type == TelephonyManager.NETWORK_TYPE_CDMA        // 电信cdma   

54.                   || type == TelephonyManager.NETWORK_TYPE_1xRTT   

55.                   || type == TelephonyManager.NETWORK_TYPE_EVDO_0   

56.                   || type == TelephonyManager.NETWORK_TYPE_EVDO_A)   

57.           {   

58.                  

59.               CdmaCellLocation cdma = (CdmaCellLocation) manager.getCellLocation();      

60.               if (cdma == null)   

61.               {   

62.                   Log.e(TAG, "CdmaCellLocation is null!!!");   

63.                   return null;   

64.               }   

65.                  

66.               int lac = cdma.getNetworkId();   

67.               String mcc = manager.getNetworkOperator().substring(0, 3);   

68.               String mnc = String.valueOf(cdma.getSystemId());   

69.               int cid = cdma.getBaseStationId();   

70.                  

71.               currentCell.cellId = cid;   

72.               currentCell.mobileCountryCode = mcc;   

73.               currentCell.mobileNetworkCode = mnc;   

74.               currentCell.locationAreaCode = lac;   

75.          

76.               currentCell.radioType = "cdma";   

77.                  

78.               CellID.add(currentCell);   

79.                  

80.               // 获得邻近基站信息   

81.               List<NeighboringCellInfo> list = manager.getNeighboringCellInfo();   

82.               int size = list.size();   

83.               for (int i = 0; i < size; i++) {   

84.     

85.                   CellIDInfo info = new CellIDInfo();   

86.                   info.cellId = list.get(i).getCid();   

87.                   info.mobileCountryCode = mcc;   

88.                   info.mobileNetworkCode = mnc;   

89.                   info.locationAreaCode = lac;   

90.                  

91.                   CellID.add(info);   

92.               }   

93.           }   

94.              

95.           return CellID;   

96.                  

97.       }  


GOOGLEAPI文档里总共有14钟网络类型,这里只罗列了其中7种,其他的主要是本人也不太清楚其对应到的网络制式是怎样的

所以部分童鞋的SIM卡网络制式不在这7种之内,自己根据实际情况看看它是归类于GSM还是CDMA在添进去就可以了


网络上多数教程是讲GSM网获取基站的,而忽略了C网的基站
这里我们可以比较一下GSM CDMA 在获取基站信息时的不同之处



GSM:

int lac = gsm.getLac();
String mcc = manager.getNetworkOperator().substring(0, 3);
String mnc = manager.getNetworkOperator().substring(3, 5);
int cid = gsm.getCid();



CDMA:

int lac = cdma.getNetworkId();
String mcc = manager.getNetworkOperator().substring(0, 3);
String mnc = String.valueOf(cdma.getSystemId());
int cid = cdma.getBaseStationId();



在获取区域码LACGSM使用的是GsmCellLocation.getLac(),CDMA则用CdmaCellLocation.getNetworkId()来代替

在获取基站IDGSM使用的是GsmCellLocation.getCid(),CDMA则用CdmaCellLocation.getBaseStationId()来代替





前面获取到的都是单个基站的信息,后面再获取周围邻近基站信息以辅助通过基站定位的精准性

TelephonyManager.getNeighboringCellInfo()
,将其也放入基站信息LIST表中





最后通过google提供的gear接口获取经纬度,代码如下:

Html代码

1.   public static Location callGear(List<CellIDInfo> cellID) {   

2.               if (cellID == null || cellID.size() == 0)    

3.                       return null;   

4.                  

5.               DefaultHttpClient client = new DefaultHttpClient();   

6.                   HttpPost post = new HttpPost("http://www.google.com/loc/json");   

7.                   JSONObject holder = new JSONObject();   

8.     

9.                   try {   

10.                           holder.put("version", "1.1.0");   

11.                           holder.put("host", "maps.google.com");   

12.                           holder.put("home_mobile_country_code", cellID.get(0).mobileCountryCode);   

13.                           holder.put("home_mobile_network_code", cellID.get(0).mobileNetworkCode);   

14.                           holder.put("radio_type", cellID.get(0).radioType);   

15.                           holder.put("request_address", true);   

16.                           if ("460".equals(cellID.get(0).mobileCountryCode))    

17.                                   holder.put("address_language", "zh_CN");   

18.                           else   

19.                                   holder.put("address_language", "en_US");   

20.                              

21.                           JSONObject data,current_data;   

22.     

23.                           JSONArray array = new JSONArray();   

24.                              

25.                           current_data = new JSONObject();   

26.                           current_data.put("cell_id", cellID.get(0).cellId);   

27.                           current_data.put("location_area_code", cellID.get(0).locationAreaCode);   

28.                           current_data.put("mobile_country_code", cellID.get(0).mobileCountryCode);   

29.                           current_data.put("mobile_network_code", cellID.get(0).mobileNetworkCode);   

30.                           current_data.put("age", 0);   

31.                           current_data.put("signal_strength", -60);   

32.                           current_data.put("timing_advance", 5555);   

33.                           array.put(current_data);   

34.                              

35.                           if (cellID.size() > 2) {   

36.                               for (int i = 1; i < cellID.size(); i++) {   

37.                                data = new JSONObject();   

38.                                data.put("cell_id", cellID.get(i).cellId);   

39.                                data.put("location_area_code", cellID.get(i).locationAreaCode);   

40.                                data.put("mobile_country_code", cellID.get(i).mobileCountryCode);   

41.                                data.put("mobile_network_code", cellID.get(i).mobileNetworkCode);   

42.                                data.put("age", 0);   

43.                                array.put(data);   

44.                               }   

45.                              }   

46.     

47.                              

48.                              

49.                              

50.                           holder.put("cell_towers", array);   

51.                                                      

52.                           StringEntity se = new StringEntity(holder.toString());   

53.                           Log.e("Location send", holder.toString());   

54.                           post.setEntity(se);   

55.                           HttpResponse resp = client.execute(post);   

56.     

57.                           HttpEntity entity = resp.getEntity();   

58.     

59.                           BufferedReader br = new BufferedReader(   

60.                                           new InputStreamReader(entity.getContent()));   

61.                           StringBuffer sb = new StringBuffer();   

62.                           String result = br.readLine();   

63.                           while (result != null) {   

64.                                   Log.e("Locaiton reseive-->", result);   

65.                                   sb.append(result);   

66.                                   result = br.readLine();   

67.                           }   

68.                              

69.                           data = new JSONObject(sb.toString());   

70.                            

71.                           data = (JSONObject) data.get("location");   

72.     

73.                           Location loc = new Location(LocationManager.NETWORK_PROVIDER);   

74.                           loc.setLatitude((Double) data.get("latitude"));   

75.                           loc.setLongitude((Double) data.get("longitude"));   

76.                           loc.setAccuracy(Float.parseFloat(data.get("accuracy").toString()));   

77.                           loc.setTime( System.currentTimeMillis());//AppUtil.getUTCTime());   

78.                           return loc;   

79.                   } catch (JSONException e) {   

80.                           e.printStackTrace();   

81.                           return null;   

82.                   } catch (UnsupportedEncodingException e) {   

83.                           e.printStackTrace();   

84.                   } catch (ClientProtocolException e) {   

85.                           e.printStackTrace();   

86.                   } catch (IOException e) {   

87.                           e.printStackTrace();   

88.                   }   

89.     

90.                   return null;   

91.           }  


大家注意看这行holder.put("radio_type", cellID.get(0).radioType);

GSM就用"gsm",CDMA就用"cdma"

这个千万别搞混了,不然就获取不到信息了

值得一提的是C网获取基站再定位那偏差不是一般的大,是恨大,将近1千米了,大概是C网基站较少的缘故吧

 

最后通过经纬度获取地理位置信息,代码如下:

Java代码

1.   public static  String getAddress(Location itude) throws Exception {   

2.           String resultString = "";   

3.       

4.           /** 这里采用get方法,直接将参数加到URL */  

5.           String urlString = String.format("http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s", itude.getLatitude(), itude.getLongitude());   

6.           Log.i("URL", urlString);   

7.       

8.           /** 新建HttpClient */  

9.           HttpClient client = new DefaultHttpClient();   

10.           /** 采用GET方法 */  

11.           HttpGet get = new HttpGet(urlString);   

12.           try {   

13.               /** 发起GET请求并获得返回数据 */  

14.               HttpResponse response = client.execute(get);   

15.               HttpEntity entity = response.getEntity();   

16.               BufferedReader buffReader = new BufferedReader(new InputStreamReader(entity.getContent()));   

17.               StringBuffer strBuff = new StringBuffer();   

18.               String result = null;   

19.               while ((result = buffReader.readLine()) != null) {   

20.                   strBuff.append(result);   

21.               }   

22.               resultString = strBuff.toString();   

23.       

24.               Log.e("resultAdress--->", resultString);   

25.                  

26.               /** 解析JSON数据,获得物理地址 */  

27.               if (resultString != null && resultString.length() > 0) {   

28.                   JSONObject jsonobject = new JSONObject(resultString);   

29.                   JSONArray jsonArray = new JSONArray(jsonobject.get("Placemark").toString());   

30.                   resultString = "";   

31.                   for (int i = 0; i < jsonArray.length(); i++) {   

32.                       resultString = jsonArray.getJSONObject(i).getString("address");   

33.                   }   

34.               }   

35.           } catch (Exception e) {   

36.               throw new Exception("获取物理位置出现错误:" + e.getMessage());   

37.           } finally {   

38.               get.abort();   

39.               client = null;   

40.           }   

41.       

42.           return resultString;   

43.       }  

 

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

©2012 粤ICP备12043775号


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