• 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()可有多种情况,如下:

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

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


    从GOOGLE的API文档里总共有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();



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

    在获取基站ID时GSM使用的是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.     }  

    在获取地理位置的这个location事实上应该传入纠偏后的location,本文暂不做此处理,所以得到的地理信息位置是偶偏差的,大家注意

    最后附上截图:

    工程下载链接:http://download.csdn.net/detail/geniuseoe2012/4340303

  • 相关阅读:
    关闭编辑easyui datagrid table
    sql 保留两位小数+四舍五入
    easyui DataGrid 工具类之 util js
    easyui DataGrid 工具类之 后台生成列
    easyui DataGrid 工具类之 WorkbookUtil class
    easyui DataGrid 工具类之 TableUtil class
    easyui DataGrid 工具类之 Utils class
    easyui DataGrid 工具类之 列属性class
    oracle 卸载
    “云时代架构”经典文章阅读感想七
  • 原文地址:https://www.cnblogs.com/qingblog/p/2598853.html
Copyright © 2020-2023  润新知