分享

使用基站、wifi实现定位

 yyLibraty 2014-03-12
         转载请注明出处 
转载于:http://fengzhizi715./blog/825716

    android可以借助于gps实现定位,但是很多地方是使用gps无法定位比如在室内,而且gps定位的话速度慢。
   
    那么如何克服这样的缺点使得应用程序在室内也可以定位呢?办法是有的借助于基站和wifi进行定位。具体的细节可参考:
http://code.google.com/intl/zh-CN/apis/gears/geolocation_network_protocol.html


    下面的代码实现了定位的大致功能
    CellIDInfo.java 封装了cellid的信息
Java代码  收藏代码
  1. public class CellIDInfo {  
  2.       
  3.     public int cellId;  
  4.     public String mobileCountryCode;  
  5.     public String mobileNetworkCode;  
  6.     public int locationAreaCode;  
  7.     public String radioType;  
  8.       
  9.     public CellIDInfo(){}  
  10. }  


        WifiInfo.java 封装了wifi的信息
Java代码  收藏代码
  1. public class WifiInfo {  
  2.       
  3.     public String mac;  
  4.       
  5.     public WifiInfo(){}  
  6. }  


        CellIDInfoManager.java 可获取所有的CellIDInfo
Java代码  收藏代码
  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3.   
  4. import android.content.Context;  
  5. import android.telephony.NeighboringCellInfo;  
  6. import android.telephony.PhoneStateListener;  
  7. import android.telephony.TelephonyManager;  
  8. import android.telephony.cdma.CdmaCellLocation;  
  9. import android.telephony.gsm.GsmCellLocation;  
  10.   
  11. public class CellIDInfoManager {  
  12.     private TelephonyManager manager;  
  13.     private PhoneStateListener listener;  
  14.     private GsmCellLocation gsm;  
  15.     private CdmaCellLocation cdma;  
  16.     int lac;  
  17.     String current_ci,mcc, mnc;  
  18.       
  19.     public CellIDInfoManager(){}  
  20.       
  21.     public ArrayList<CellIDInfo> getCellIDInfo(Context context){  
  22.         manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);  
  23.         listener = new PhoneStateListener();  
  24.         manager.listen(listener, 0);  
  25.         ArrayList<CellIDInfo> CellID = new ArrayList<CellIDInfo>();  
  26.         CellIDInfo currentCell = new CellIDInfo();  
  27.           
  28.         int type = manager.getNetworkType();  
  29.   
  30.         if (type == TelephonyManager.NETWORK_TYPE_GPRS || type ==TelephonyManager.NETWORK_TYPE_EDGE  
  31.                 || type ==TelephonyManager.NETWORK_TYPE_HSDPA) {  
  32.             gsm = ((GsmCellLocation) manager.getCellLocation());  
  33.             if (gsm == null) return null;  
  34.             lac  = gsm.getLac();  
  35.             mcc = manager.getNetworkOperator().substring(0, 3);  
  36.             mnc = manager.getNetworkOperator().substring(3, 5);  
  37.               
  38.             currentCell.cellId = gsm.getCid();  
  39.             currentCell.mobileCountryCode = mcc;  
  40.             currentCell.mobileNetworkCode = mnc;  
  41.             currentCell.locationAreaCode = lac;  
  42.             currentCell.radioType = "gsm";  
  43.             CellID.add(currentCell);  
  44.               
  45.             List<NeighboringCellInfo> list = manager.getNeighboringCellInfo();  
  46.             int size = list.size();  
  47.             for (int i = 0; i < size; i++) {  
  48.                 CellIDInfo info = new CellIDInfo();  
  49.                 info.cellId = list.get(i).getCid();  
  50.                 info.mobileCountryCode = mcc;  
  51.                 info.mobileCountryCode = mnc;  
  52.                 info.locationAreaCode = lac;  
  53.                 CellID.add(info);  
  54.             }  
  55.             return CellID;  
  56.               
  57.         } else if (type == TelephonyManager.NETWORK_TYPE_CDMA || type ==TelephonyManager.NETWORK_TYPE_1xRTT) {  
  58.             cdma = ((CdmaCellLocation) manager.getCellLocation());  
  59.             if (cdma == null) return null;  
  60.               
  61.             if ("460".equals(manager.getSimOperator().substring(0, 3)))   
  62.                 return null;  
  63.         }  
  64.         return null;  
  65.     }  
  66. }  



       WifiInfoManager.java 可获取wifi的信息,目前我只取了当前连接的wifi,没有获取所有能扫描到的wifi信息。
Java代码  收藏代码
  1. import java.util.ArrayList;  
  2.   
  3. import android.content.Context;  
  4. import android.net.wifi.WifiManager;  
  5.   
  6. public class WifiInfoManager {  
  7.       
  8.     WifiManager wm;  
  9.       
  10.     public WifiInfoManager(){}  
  11.       
  12.     public ArrayList getWifiInfo(Context context){  
  13.         ArrayList<WifiInfo> wifi = new ArrayList();  
  14.         wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);  
  15.         WifiInfo info = new WifiInfo();  
  16.         info.mac = wm.getConnectionInfo().getBSSID();  
  17.         wifi.add(info);  
  18.         return wifi;  
  19.     }  
  20. }  


       调用google gears的方法,该方法调用gears来获取经纬度
Java代码  收藏代码
  1. private Location callGear(ArrayList<WifiInfo> wifi,  
  2.             ArrayList<CellIDInfo> cellID) {  
  3.           
  4.         if (cellID == null) return null;  
  5.           
  6.         DefaultHttpClient client = new DefaultHttpClient();  
  7.   
  8.         HttpPost post = new HttpPost(  
  9.                 "http://www.google.com/loc/json");  
  10.         JSONObject holder = new JSONObject();  
  11.   
  12.         try {  
  13.             holder.put("version", "1.1.0");  
  14.             holder.put("host", "maps.google.com");  
  15.             holder.put("home_mobile_country_code", cellID.get(0).mobileCountryCode);  
  16.             holder.put("home_mobile_network_code", cellID.get(0).mobileNetworkCode);  
  17.             holder.put("radio_type", cellID.get(0).radioType);  
  18.             holder.put("request_address", true);  
  19.             if ("460".equals(cellID.get(0).mobileCountryCode))   
  20.                 holder.put("address_language", "zh_CN");  
  21.             else  
  22.                 holder.put("address_language", "en_US");  
  23.               
  24.             JSONObject data,current_data;  
  25.   
  26.             JSONArray array = new JSONArray();  
  27.               
  28.             current_data = new JSONObject();  
  29.             current_data.put("cell_id", cellID.get(0).cellId);  
  30.             current_data.put("mobile_country_code", cellID.get(0).mobileCountryCode);  
  31.             current_data.put("mobile_network_code", cellID.get(0).mobileNetworkCode);  
  32.             current_data.put("age", 0);  
  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(0).locationAreaCode);  
  40.                     data.put("mobile_country_code", cellID.get(0).mobileCountryCode);  
  41.                     data.put("mobile_network_code", cellID.get(0).mobileNetworkCode);  
  42.                     data.put("age", 0);  
  43.                     array.put(data);  
  44.                 }  
  45.             }  
  46.             holder.put("cell_towers", array);  
  47.               
  48.             if (wifi.get(0).mac != null) {  
  49.                 data = new JSONObject();  
  50.                 data.put("mac_address", wifi.get(0).mac);  
  51.                 data.put("signal_strength", 8);  
  52.                 data.put("age", 0);  
  53.                 array = new JSONArray();  
  54.                 array.put(data);  
  55.                 holder.put("wifi_towers", array);  
  56.             }  
  57.               
  58.             StringEntity se = new StringEntity(holder.toString());  
  59.             Log.e("Location send", holder.toString());  
  60.             post.setEntity(se);  
  61.             HttpResponse resp = client.execute(post);  
  62.   
  63.             HttpEntity entity = resp.getEntity();  
  64.   
  65.             BufferedReader br = new BufferedReader(  
  66.                     new InputStreamReader(entity.getContent()));  
  67.             StringBuffer sb = new StringBuffer();  
  68.             String result = br.readLine();  
  69.             while (result != null) {  
  70.                 Log.e("Locaiton reseive", result);  
  71.                 sb.append(result);  
  72.                 result = br.readLine();  
  73.             }  
  74.   
  75.             data = new JSONObject(sb.toString());  
  76.             data = (JSONObject) data.get("location");  
  77.   
  78.             Location loc = new Location(LocationManager.NETWORK_PROVIDER);  
  79.             loc.setLatitude((Double) data.get("latitude"));  
  80.             loc.setLongitude((Double) data.get("longitude"));  
  81.             loc.setAccuracy(Float.parseFloat(data.get("accuracy").toString()));  
  82.             loc.setTime(AppUtil.getUTCTime());  
  83.             return loc;  
  84.         } catch (JSONException e) {  
  85.             return null;  
  86.         } catch (UnsupportedEncodingException e) {  
  87.             e.printStackTrace();  
  88.         } catch (ClientProtocolException e) {  
  89.             e.printStackTrace();  
  90.         } catch (IOException e) {  
  91.             e.printStackTrace();  
  92.         }  
  93.         return null;  
  94.     }  


   目前已经测试过中国移动、联通的卡,以及测试过中兴的MIC,都可以准确定位。
   不支持的是cdma,将cdma的数据传入到gears后返回的经纬度显示是在美国。

   提外话,将gps和基站、wifi三者定位结合的话效果更好。基站的定位没有wifi准确,gps的定位速度比基站、wifi都来得更慢。   

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多