Android的WiFi,GPS,基站定位

Android結(jié)合WiFi、GPS和基站的定位,定義的定位流程為WiFi-->>GPS-->>基站,精確度來說,

WiFi是最高的,不過WiFi定位需要依賴于周邊環(huán)境,附近的WiFi越多,定位就越準(zhǔn)確,在一些鄉(xiāng)鎮(zhèn)城市的話,WiFi定位可能就沒有那么精確。
GPS定位在室內(nèi)的話,基本是無法獲取到定位信息的,不過在室外空曠一點(diǎn)的地方,GPS定位還是比較精確的。
基站定位的話,不多說,精確度偏差是最大的了。

1.WiFi定位

WiFi定位的原理大致是,因?yàn)槊恳粋€(gè)無線AP都有一個(gè)全球唯一的MAC地址,就是獲取到WiFi的MAC地址然后去后臺(tái)數(shù)據(jù)庫(kù)去匹配(這個(gè)需要后臺(tái)數(shù)據(jù)庫(kù)足夠強(qiáng)大,越強(qiáng)大匹配的越準(zhǔn))。這邊提供一個(gè)WiFi地址查詢的地址:點(diǎn)擊我(如侵刪)

1.1掃描手機(jī)當(dāng)前連接的WiFi(WiFi開啟關(guān)閉狀態(tài),以下就直接忽略不寫,具體使用的時(shí)候需要注意)
<!--WiFi狀態(tài)讀取權(quán)限-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
//獲取當(dāng)前連接的WiFi
WifiInfo info = wifiManager .getConnectionInfo();
1.2得到當(dāng)前WiFi對(duì)象信息,BSSID對(duì)應(yīng)為Mac地址
WiFi對(duì)象信息
WiFi定位的原則是最好能獲取到附近的幾個(gè)WiFi熱點(diǎn),然后將幾個(gè)WiFi進(jìn)行位置的糾偏。

2.GPS定位

<!-- GPS權(quán)限 -->
   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
需要打開手機(jī)GPS的位置信息模式為:高精度,這一步很重要,會(huì)一直都無法獲取到定位信息
模式:高精度
開始定位
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
//獲取所有可用的位置提供器
List<String> providers = locationManager.getProviders(true);
if (providers.contains(LocationManager.GPS_PROVIDER)) {
   //GPS定位
  locationProvider = LocationManager.GPS_PROVIDER;
  startRequestLocationUpdates(locationProvider, 0, 0);
} else if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
  // Network定位
  locationProvider = LocationManager.NETWORK_PROVIDER;
  if (locationManager.getAllProviders().contains(LocationManager.NETWORK_PROVIDER) &&     
    locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
    startRequestLocationUpdates(locationProvider, 0, 0);
  }
} else {
  //沒有可用的位置提供器,GPS定位失敗
}

/**
* 開始請(qǐng)求gps定位
*
* @param locationProvider 參數(shù)1,設(shè)備:有GPS_PROVIDER和NETWORK_PROVIDER兩種,前者是GPS,后者是GPRS以及WIFI定位
* @param minTime  位置信息更新周期.單位是毫秒
* @param minDistance  位置變化最小距離:當(dāng)位置距離變化超過此值時(shí),將更新位置信息
* 備注:參數(shù)2和3,如果參數(shù)3不為0,則以參數(shù)3為準(zhǔn);參數(shù)3為0,則通過時(shí)間來定時(shí)更新;兩者為0,則隨時(shí)刷新
*/
 private void startRequestLocationUpdates(String locationProvider, long minTime, float minDistance) {
     locationManager.requestLocationUpdates(locationProvider, minTime, minDistance, locationListener);
 }

//監(jiān)聽回調(diào)
LocationListener locationListener = new LocationListener() {
           @Override
           public void onLocationChanged(Location location) {
                //位置信息變化時(shí)觸發(fā),一旦觸發(fā)這個(gè)回調(diào)就證明GPS定位成功,這個(gè)方法是一直都會(huì)回調(diào)的,在一定的時(shí)間內(nèi),需要設(shè)置一個(gè)超時(shí),以免耗電。
           }
           @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
                switch (status) {
                    case LocationProvider.AVAILABLE:
                       //當(dāng)前GPS狀態(tài)為可見狀態(tài)
                        break;
                    case LocationProvider.OUT_OF_SERVICE:
                       //當(dāng)前GPS狀態(tài)為服務(wù)區(qū)外狀態(tài)
                        break;
                    case LocationProvider.TEMPORARILY_UNAVAILABLE:
                        //當(dāng)前GPS狀態(tài)為暫停服務(wù)狀態(tài)
                        break;
                    default:
                        break;
                }
            }
            @Override
            public void onProviderEnabled(String provider) {
                //GPS開啟時(shí)觸發(fā)
            }

            @Override
            public void onProviderDisabled(String provider) {
               //GPS禁用時(shí)觸發(fā)
            }
}
一旦觸發(fā)onLocationChanged方法就可以得到GPS返回的經(jīng)緯度,你就可以通過這個(gè)經(jīng)緯去取查詢位置啦。點(diǎn)擊查詢GPS定位(如侵刪)
關(guān)閉GPS定位
if (locationManager != null) {
  locationManager.removeUpdates(locationListener);
  locationManager = null;
}
if (locationListener != null) {
  locationListener = null;
}

3.基站定位

基站的一些參數(shù)說明:
MCC,Mobile Country Code,移動(dòng)國(guó)家代碼(中國(guó)的為460);
MNC,Mobile Network Code,移動(dòng)網(wǎng)絡(luò)號(hào)碼(中國(guó)移動(dòng)為0,中國(guó)聯(lián)通為1,中國(guó)電信為2);
LAC,Location Area Code,位置區(qū)域碼;
CID,Cell Identity,基站編號(hào);
BSSS,Base station signal strength,基站信號(hào)強(qiáng)度。
1.1獲取當(dāng)前手機(jī)連接的基站信息
TelephonyManager mTelephonyManager = (TelephonyManager) mContext.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
        if (mTelephonyManager == null) {
            return;
        }
        String operator = mTelephonyManager.getNetworkOperator();
        //獲取的基站信息是
        if (operator == null || operator.length() < 5) {
           //獲取基站信息有問題,可能是手機(jī)沒插sim卡
            return;
        }
        int mcc = Integer.parseInt(operator.substring(0, 3));
        int mnc = Integer.parseInt(operator.substring(3));
        int lac;
        int cellId;
        CellLocation cellLocation = mTelephonyManager.getCellLocation();
        if (cellLocation == null) {
            //可能是手機(jī)沒插sim卡之類的,返回獲取基站失敗
            return;
        }
//因?yàn)橐苿?dòng)聯(lián)通電信基站的不同,所以需要區(qū)分基站類型
//中國(guó)移動(dòng)和中國(guó)聯(lián)通獲取LAC,CID的方式
if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
           //當(dāng)前連接的是gsm基站
            GsmCellLocation location = (GsmCellLocation) cellLocation;
            lac = location.getLac();
            cellId = location.getCid();
            BaseStationInfo baseStationInfo = new BaseStationInfo();
            baseStationInfo.setMcc(mcc);
            baseStationInfo.setMnc(mnc);
            baseStationInfo.setLac(lac);
            baseStationInfo.setCid(cellId);
            baseStationInfo.setBaseType(0);
}
//中國(guó)電信獲取LAC,CID的方式
if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
            //當(dāng)前連接是cdma基站
            CdmaCellLocation cdma = (CdmaCellLocation) mTelephonyManager.getCellLocation();
            BaseStationInfo baseStationInfo = new BaseStationInfo();
            baseStationInfo.setBaseType(1);
            baseStationInfo.setSid(cdma.getSystemId());
            baseStationInfo.setNid(cdma.getNetworkId());
            baseStationInfo.setBid(cdma.getBaseStationId());
}
1.2獲取獲取附近的基站信息
// 獲取鄰區(qū)基站信息
List<CellInfo> infos = mTelephonyManager.getAllCellInfo();
if(infos==null){
  //沒有獲取附近任何的基站信息
  return;
}
基站類型的話,也是分為好幾種類型的,需要做區(qū)分的處理
for (CellInfo i : infos) {
  if (i instanceof CellInfoGsm) {//gsm基站
    Log.i(TAG, "附近發(fā)現(xiàn)gsm基站Mcc = " + cellIdentityGsm.getMcc());
    Log.i(TAG, "附近發(fā)現(xiàn)gsm基站Mnc = " + cellIdentityGsm.getMnc());
    Log.i(TAG, "附近發(fā)現(xiàn)gsm基站Lac = " + cellIdentityGsm.getLac());
    Log.i(TAG, "附近發(fā)現(xiàn)gsm基站Cid = " + cellIdentityGsm.getCid());
  }else if (i instanceof CellInfoCdma) {//cdma基站
    Log.i(TAG, "附近發(fā)現(xiàn)cdma基站sid = " + cellIdentityCdma.getSystemId());
    Log.i(TAG, "附近發(fā)現(xiàn)cdma基站nid = " + cellIdentityCdma.getNetworkId());
    Log.i(TAG, "附近發(fā)現(xiàn)cdma基站sid = " + cellIdentityCdma.getBasestationId());
  }else if (i instanceof CellInfoLte) {//lte基站
    Log.i(TAG, "附近發(fā)現(xiàn)lte基站Mcc = " + cellIdentityLte.getMcc());
    Log.i(TAG, "附近發(fā)現(xiàn)lte基站Mnc = " + cellIdentityLte.getMnc());
    Log.i(TAG, "附近發(fā)現(xiàn)lte基站Lac = " + cellIdentityLte.getTac());
    Log.i(TAG, "附近發(fā)現(xiàn)lte基站Cid = " + cellIdentityLte.getCi());
  }else if (i instanceof CellInfoWcdma) {//wcdma基站
    Log.i(TAG, "附近發(fā)現(xiàn)wcdma基站Mcc = " + cellIdentityWcdma.getMcc());
    Log.i(TAG, "附近發(fā)現(xiàn)wcdma基站Mnc = " + cellIdentityWcdma.getMnc());
    Log.i(TAG, "附近發(fā)現(xiàn)wcdma基站Lac = " + cellIdentityWcdma.getLac());
    Log.i(TAG, "附近發(fā)現(xiàn)wcdma基站Cid = " + cellIdentityWcdma.getCid());
  }
}
以上得到基站信息,即可進(jìn)行查詢點(diǎn)擊查詢基站定位(如侵刪)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容