您的位置:首页 > 编程语言 > Java开发

使用基站、wifi实现定位

2012-07-10 14:09 435 查看
 android可以借助于gps实现定位,但是很多地方是使用gps无法定位比如在室内,而且gps定位的话速度慢。 
    
    那么如何克服这样的缺点使得应用程序在室内也可以定位呢?办法是有的借助于基站和wifi进行定位。具体的细节可参考:  http://code.google.com/intl/zh-CN/apis/gears/geolocation_network_protocol.html 
    下面的代码实现了定位的大致功能 
    CellIDInfo.java 封装了cellid的信息 

Java代码  



public class CellIDInfo {  

      

    public int cellId;  

    public String mobileCountryCode;  

    public String mobileNetworkCode;  

    public int locationAreaCode;  

    public String radioType;  

      

    public CellIDInfo(){}  

}  

        WifiInfo.java 封装了wifi的信息 

Java代码  



public class WifiInfo {  

      

    public String mac;  

      

    public WifiInfo(){}  

}  

        CellIDInfoManager.java 可获取所有的CellIDInfo 

Java代码  



import java.util.ArrayList;  

import java.util.List;  

  

import android.content.Context;  

import android.telephony.NeighboringCellInfo;  

import android.telephony.PhoneStateListener;  

import android.telephony.TelephonyManager;  

import android.telephony.cdma.CdmaCellLocation;  

import android.telephony.gsm.GsmCellLocation;  

  

public class CellIDInfoManager {  

    private TelephonyManager manager;  

    private PhoneStateListener listener;  

    private GsmCellLocation gsm;  

    private CdmaCellLocation cdma;  

    int lac;  

    String current_ci,mcc, mnc;  

      

    public CellIDInfoManager(){}  

      

    public ArrayList<CellIDInfo> getCellIDInfo(Context context){  

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

        listener = new PhoneStateListener();  

        manager.listen(listener, 0);  

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

        CellIDInfo currentCell = new CellIDInfo();  

          

        int type = manager.getNetworkType();  

  

        if (type == TelephonyManager.NETWORK_TYPE_GPRS || type ==TelephonyManager.NETWORK_TYPE_EDGE  

                || type ==TelephonyManager.NETWORK_TYPE_HSDPA) {  

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

            if (gsm == null) return null;  

            lac  = gsm.getLac();  

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

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

              

            currentCell.cellId = gsm.getCid();  

            currentCell.mobileCountryCode = mcc;  

            currentCell.mobileNetworkCode = mnc;  

            currentCell.locationAreaCode = lac;  

            currentCell.radioType = "gsm";  

            CellID.add(currentCell);  

              

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

            int size = list.size();  

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

                CellIDInfo info = new CellIDInfo();  

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

                info.mobileCountryCode = mcc;  

                info.mobileCountryCode = mnc;  

                info.locationAreaCode = lac;  

                CellID.add(info);  

            }  

            return CellID;  

              

        } else if (type == TelephonyManager.NETWORK_TYPE_CDMA || type ==TelephonyManager.NETWORK_TYPE_1xRTT) {  

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

            if (cdma == null) return null;  

              

            if ("460".equals(manager.getSimOperator().substring(0, 3)))   

                return null;  

        }  

        return null;  

    }  

}  

       WifiInfoManager.java 可获取wifi的信息,目前我只取了当前连接的wifi,没有获取所有能扫描到的wifi信息。 

Java代码  



import java.util.ArrayList;  

  

import android.content.Context;  

import android.net.wifi.WifiManager;  

  

public class WifiInfoManager {  

      

    WifiManager wm;  

      

    public WifiInfoManager(){}  

      

    public ArrayList getWifiInfo(Context context){  

        ArrayList<WifiInfo> wifi = new ArrayList();  

        wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);  

        WifiInfo info = new WifiInfo();  

        info.mac = wm.getConnectionInfo().getBSSID();  

        wifi.add(info);  

        return wifi;  

    }  

}  

       调用google gears的方法,该方法调用gears来获取经纬度 

Java代码  



private Location callGear(ArrayList<WifiInfo> wifi,  

            ArrayList<CellIDInfo> cellID) {  

          

        if (cellID == null) return null;  

          

        DefaultHttpClient client = new DefaultHttpClient();  

  

        HttpPost post = new HttpPost(  

                "http://www.google.com/loc/json");  

        JSONObject holder = new JSONObject();  

  

        try {  

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

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

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

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

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

            holder.put("request_address", true);  

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

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

            else  

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

              

            JSONObject data,current_data;  

  

            JSONArray array = new JSONArray();  

              

            current_data = new JSONObject();  

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

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

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

            current_data.put("age", 0);  

            array.put(current_data);  

              

            if (cellID.size() > 2) {  

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

                    data = new JSONObject();  

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

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

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

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

                    data.put("age", 0);  

                    array.put(data);  

                }  

            }  

            holder.put("cell_towers", array);  

              

            if (wifi.get(0).mac != null) {  

                data = new JSONObject();  

                data.put("mac_address", wifi.get(0).mac);  

                data.put("signal_strength", 8);  

                data.put("age", 0);  

                array = new JSONArray();  

                array.put(data);  

                holder.put("wifi_towers", array);  

            }  

              

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

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

            post.setEntity(se);  

            HttpResponse resp = client.execute(post);  

  

            HttpEntity entity = resp.getEntity();  

  

            BufferedReader br = new BufferedReader(  

                    new InputStreamReader(entity.getContent()));  

            StringBuffer sb = new StringBuffer();  

            String result = br.readLine();  

            while (result != null) {  

                Log.e("Locaiton reseive", result);  

                sb.append(result);  

                result = br.readLine();  

            }  

  

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

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

  

            Location loc = new Location(LocationManager.NETWORK_PROVIDER);  

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

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

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

            loc.setTime(AppUtil.getUTCTime());  

            return loc;  

        } catch (JSONException e) {  

            return null;  

        } catch (UnsupportedEncodingException e) {  

            e.printStackTrace();  

        } catch (ClientProtocolException e) {  

            e.printStackTrace();  

        } catch (IOException e) {  

            e.printStackTrace();  

        }  

        return null;  

    }  

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

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

转自(http://fengzhizi715.iteye.com/blog/825716)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息