zoukankan      html  css  js  c++  java
  • Android 基站定位源代码

    Android 基站定位源代码

    经过几天的调研以及测试,终于解决了联通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()
    在源代码里面有如下的类型定义

    /** Network type is unknown */
        public static final int NETWORK_TYPE_UNKNOWN = 0;
        /** Current network is GPRS */
        public static final int NETWORK_TYPE_GPRS = 1;
        /** Current network is EDGE */
        public static final int NETWORK_TYPE_EDGE = 2;
        /** Current network is UMTS */
        public static final int NETWORK_TYPE_UMTS = 3;
        /** Current network is CDMA: Either IS95A or IS95B*/
        public static final int NETWORK_TYPE_CDMA = 4;
        /** Current network is EVDO revision 0*/
        public static final int NETWORK_TYPE_EVDO_0 = 5;
        /** Current network is EVDO revision A*/
        public static final int NETWORK_TYPE_EVDO_A = 6;
        /** Current network is 1xRTT*/
        public static final int NETWORK_TYPE_1xRTT = 7;
        /** Current network is HSDPA */
        public static final int NETWORK_TYPE_HSDPA = 8;
        /** Current network is HSUPA */
        public static final int NETWORK_TYPE_HSUPA = 9;
        /** Current network is HSPA */
        public static final int NETWORK_TYPE_HSPA = 10;

    2 联通、移动、电信不同制式在获取基站位置的代码区别。

    这部分是我实际测试出来的,经过无数次的拆机,放卡,才实现了不同制式的完美实现。
    代码如下:

    TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    int type = tm.getNetworkType();
    //中国电信为CTC
    //NETWORK_TYPE_EVDO_A是中国电信3G的getNetworkType
    //NETWORK_TYPE_CDMA电信2G是CDMA
    if (type == TelephonyManager.NETWORK_TYPE_EVDO_A || type == TelephonyManager.NETWORK_TYPE_CDMA || type ==TelephonyManager.NETWORK_TYPE_1xRTT)
    {
    }
    //移动2G卡 + CMCC + 2
    //type = NETWORK_TYPE_EDGE
    else if(type == TelephonyManager.NETWORK_TYPE_EDGE)
    {
    }
    //联通的2G经过测试 China Unicom   1 NETWORK_TYPE_GPRS
    else if(type == TelephonyManager.NETWORK_TYPE_GPRS)
    {
     
    }
    else
    {
    tv.setText("Current Not Support This Type.");
    }

    3 通过基站的基本信息,通过Google Gears获取对应的GPS经纬度。
    这部分前面的两篇文章都有提到,代码参考了网友们的代码,感谢感谢。

    private Location callGear(ArrayList 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("location_area_code", cellID.get(0).locationAreaCode);
                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(i).locationAreaCode);
                        data.put("mobile_country_code", cellID.get(i).mobileCountryCode);
                        data.put("mobile_network_code", cellID.get(i).mobileNetworkCode);
                        data.put("age", 0);
                        array.put(data);
                    }
                }
                holder.put("cell_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 receive", result);
                    sb.append(result);
                    result = br.readLine();
                }
                if(sb.length()              return null;
                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(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;
        }

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

    private String getLocation(Location itude) throws Exception {
            String resultString = "";
     
            /** 这里采用get方法,直接将参数加到URL上 */
            String urlString = String.format("http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s", itude.getLatitude(), itude.getLongitude());
            Log.i("URL", urlString);
     
            /** 新建HttpClient */
            HttpClient client = new DefaultHttpClient();
            /** 采用GET方法 */
            HttpGet get = new HttpGet(urlString);
            try {
                /** 发起GET请求并获得返回数据 */
                HttpResponse response = client.execute(get);
                HttpEntity entity = response.getEntity();
                BufferedReader buffReader = new BufferedReader(new InputStreamReader(entity.getContent()));
                StringBuffer strBuff = new StringBuffer();
                String result = null;
                while ((result = buffReader.readLine()) != null) {
                    strBuff.append(result);
                }
                resultString = strBuff.toString();
     
                /** 解析JSON数据,获得物理地址 */
                if (resultString != null && resultString.length() > 0) {
                    JSONObject jsonobject = new JSONObject(resultString);
                    JSONArray jsonArray = new JSONArray(jsonobject.get("Placemark").toString());
                    resultString = "";
                    for (int i = 0; i < jsonArray.length(); i++) {
                        resultString = jsonArray.getJSONObject(i).getString("address");
                    }
                }
            } catch (Exception e) {
                throw new Exception("获取物理位置出现错误:" + e.getMessage());
            } finally {
                get.abort();
                client = null;
            }
     
            return resultString;
        }

    5 最关键的出来了,附上代码吧。
    AndroidPosition
    补充一下:
    在AndroidMenifest.xml里面需要加上
    android.permission.INTERNET、android.permission.ACCESS_COARSE_LOCATION、android.permission.READ_PHONE_STATE权限,否则会出错。
    放在Application包前面。

    6 图片看一下效果吧。

    20120224181116.png

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

    转自:http://www.cnblogs.com/doandroid/archive/2012/02/24/Android_Base_Station_Location.html

  • 相关阅读:
    HTTP协议
    JavaScript学习(一)
    Cookie&Session
    注解初学
    反射初学
    XML
    Web概念
    Response对象
    Servlet
    LeetCode Notes_#617 Merge Two Binary Trees
  • 原文地址:https://www.cnblogs.com/blogsme/p/2919171.html
Copyright © 2011-2022 走看看