Android 基站定位源代碼

openkk 12年前發布 | 65K 次閱讀 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."); }</pre>3 通過基站的基本信息,通過Google Gears獲取對應的GPS經緯度。
這部分前面的兩篇文章都有提到,代碼參考了網友們的代碼,感謝感謝。

private Location callGear(ArrayList cellID) {
        if (cellID == null) return null;
        DefaultHttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(
                "

        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;
}</pre> <p></p>

</div>

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;
}</pre> <p></p>

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

-End-


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

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!