Android基站定位基本應用

概述

本篇主要介紹android基站定位的基本思路,解釋了下用到的TelephonyManager的一些方法。最后介紹了google定位服務與android提供參數之間的聯系。

基站定位原理:

通過手機信號獲取基站信息,然后調用第三方服務的根據基站信息查找基站的經緯度值。
盡管根據基站網絡制式不同(cdma或gsm)所獲取的基站信息也不一樣,但一般用谷歌等這樣的第三方定位服務需要獲得這些基站信息:

  1. MCC,Mobile Country Code,移動國家代碼(中國的為460)。
  2. MNC,Mobile Network Code,移動網絡號碼(中國移動為0,中國聯通為1,中國電信為2)。
  3. LAC,Location Area Code,位置區域碼。
  4. CID,Cell Identity,基站編號。
  5. BSSS,Base station signal strength,基站信號強度。

Android基站信息api

獲取網絡服務商信息MNC&MCC

從系統服務中獲取TelephonyManager:

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

TelephonyManager#getNetworkOperator方法獲取目前注冊網絡MCC+MNC信息,一般是5-6位的字符串,前3位為MCC,后面的是MNC。
用戶必須在該網絡注冊才能獲取到信息,對于cdma網絡而言可能會不靠譜,因此用TelephonyManager#getPhoneType來判斷手機支持的網絡制式。

String operator = telephonyManager.getNetworkOperator();
String mcc = operator.substring(0, 3);
String mnc = operator.substring(3);

TelephonyManager#getSimOperator方法獲取Sim卡的MCC+MNC信息
SM卡狀態必須處于SIM_STATE_READY,用TelephonyManager#getSimState判斷Sim卡狀態。

TelephonyManager#getPhoneType 獲取手機支持網絡制式
一般就GSM、CDMA兩種,如果沒有獲取到則是NONE。

TelephonyManager#getNetWorkType 獲取網絡類型
用以區分移動2g,電信4g等更具體的網絡。

獲取當前連接基站信息LAC、CID

由于電信用的是cdma制式網絡,移動和聯通用的gsm網絡,這兩種網絡基站信息封裝類在android中是不同的,cdma要用CdmaCellLocation,gsm要用GsmCellLocation。
從TelephonManager獲取基站定位信息CellLocation,其中封裝了需要的CID和LAC等信息。

if(telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA){
    CdmaCellLocation cdmaCellLocation = (CdmaCellLocation) 
telephonyManager.getCellLocation();
    int cid = cdmaCellLocation.getBaseStationId(); //獲取cdma基站識別標號 BID
    int lac = cdmaCellLocation.getNetworkId(); //獲取cdma網絡編號NID
    int sid = cdmaCellLocation.getSystemId(); //用谷歌API的話cdma網絡的mnc要用這個getSystemId()取得→SID
}else{
    GsmCellLocation gsmCellLocation = (GsmCellLocation) telephonyManager.getCellLocation();
    int cid = gsmCellLocation.getCid(); //獲取gsm基站識別標號
    int lac = gsmCellLocation.getLac(); //獲取gsm網絡編號
}

獲取鄰近基站信號強度信息BSSS

每個基站信息封裝在具體CellInfo子類中,有CellInfoCdma、CellInfoGsm等。CellInfoGsm中又封裝了2個函數,分別用來返回基站識別信息(CellIdentityGsm類)和基站信號強度信息(CellSignalStrengthGsm類)。

TelephonyManager#getAllCellInfo方法返回所有能檢測到的基站信息(包括連接的基站信息),而且返回的信息更詳細。而TelephonyManager#getNeighboringCellInfo方法不包括連接的基站信息,返回基站信息是經過處理的,不加以cdma或gsm區分。一般用getAllCellInfo方法。

List<CellInfo> infoLists = telephonyManager.getAllCellInfo();
    for (CellInfo info : infoLists) {
        CellInfoCdma cellInfoCdma = (CellInfoCdma) info;
        CellIdentityCdma cellIdentityCdma = cellInfoCdma.getCellIdentity();
        CellSignalStrengthCdma cellSignalStrengthCdma = cellInfoCdma.getCellSignalStrength();
        int strength = cellSignalStrengthCdma.getCdmaDbm();
        int cid = cellIdentityCdma.getBasestationId();
        // 處理 strength和id數據
    }

CellSignalStrengthCdma類中封裝了各種信號處理方法,用來返回不同標準的信號強度。CellIdentityCdma類封裝了Cdma基站特有的識別信息,比如能通過CellIdentityCdma#getLongitude()獲取Cdma基站的經緯度。CellIdentityGsm類封裝Gsm基站信息,能獲取MCC、MNC、CID和LAC。

Android 基站信息監聽器

PhoneStateListener類是一個監聽類,重寫其中方法實現對基站信息變化的監聽。

private PhoneStateListener phoneStateListener; //定義監聽器
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CELL_LOCATION); //注冊監聽器,設定不同的監聽類型
//設置監聽器方法
private void setPhoneStateListener(){
    phoneStateListener = new PhoneStateListener(){
        @Override
         public void onCellLocationChanged(CellLocation location){}
        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {}
        @Override
        public void onCellInfoChanged(List<CellInfo> cellInfo) {}
    }
}

這里主要用到的三個回調函數:

  • onCellLocationChanged 當cellLocation變化時會調用,傳入cellLocation類型,需要根據具體的網絡制式向下轉型(CdmaCellLocation或GsmCellLocation)。

  • onSignalStrengthsChanged 傳入的是SignalStrength類型,這個類型和CellStrength類沒關系,是一個重新寫的類。其中有自定義的一些方法返回信號強度,有getCdmaDbm()、getGsmSignalStrength()。Coma和gsm類型都封裝在一起,需要調用額外的方法isGsm()。

  • onCellInfoChanged 傳入參數為CellInfo,維護一個CellInfo列表,有檢測到的基站變動都會調用。方法跟TelephonyManager#getAllCellInfo()的使用類似。

google定位服務API

移動電話基站Json

google的基站定位服務所需參數:

"homeMobileCountryCode": 310,  //即MCC
  "homeMobileNetworkCode": 410,   //即MNC
  "radioType": "gsm",
  "carrier": "Vodafone",
  "considerIp": "true",
  "cellTowers": [
    // See the Cell Tower Objects section below.
  ]

cellTower就是之前說的信號強度BSSS參數,需要一個列表來記錄周圍基站參數。cellTower并不是必要參數,但是給了可以增加定位精確度。

{
  "cellTowers": [
    {
      "cellId": 42,
      "locationAreaCode": 415,
      "mobileCountryCode": 310,
      "mobileNetworkCode": 410,
      "age": 0,
      "signalStrength": -60,
      "timingAdvance": 15
    }
  ]
}

CellTowers必填字段:

  • cellId(必填): GSM用的是CID,CDMA 網絡使用的是基站 ID (BID)。WCDMA 網絡使用 UTRAN/GERAN 基站標識 (UC-Id),這是一個 32 位的值,由無線網絡控制器 (RNC) 和基站 ID 連接而成。在 WCDMA 網絡中,如果只指定 16 位的基站 ID 值,返回的結果可能會不準確。
  • locationAreaCode(必填):GSM 和 WCDMA 網絡的位置區域代碼 (LAC)。CDMA 網絡的網絡 ID (NID)。
  • mobileCountryCode(必填):移動電話基站的移動國家代碼 (MCC)。
  • mobileNetworkCode(必填):移動電話基站的移動網絡代碼。對于 GSM 和 WCDMA,這就是 MNC;CDMA 使用的是系統 ID (SID)。

參考鏈接

Google Maps Geolocation API
Android參考文檔 TelephonyManager

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容