美文网首页
Android的WiFi,GPS,基站定位

Android的WiFi,GPS,基站定位

作者: binlees | 来源:发表于2019-04-02 17:36 被阅读0次
Android结合WiFi、GPS和基站的定位,定义的定位流程为WiFi-->>GPS-->>基站,精确度来说,

WiFi是最高的,不过WiFi定位需要依赖于周边环境,附近的WiFi越多,定位就越准确,在一些乡镇城市的话,WiFi定位可能就没有那么精确。
GPS定位在室内的话,基本是无法获取到定位信息的,不过在室外空旷一点的地方,GPS定位还是比较精确的。
基站定位的话,不多说,精确度偏差是最大的了。

1.WiFi定位

WiFi定位的原理大致是,因为每一个无线AP都有一个全球唯一的MAC地址,就是获取到WiFi的MAC地址然后去后台数据库去匹配(这个需要后台数据库足够强大,越强大匹配的越准)。这边提供一个WiFi地址查询的地址:点击我(如侵删)

1.1扫描手机当前连接的WiFi(WiFi开启关闭状态,以下就直接忽略不写,具体使用的时候需要注意)
<!--WiFi状态读取权限-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
//获取当前连接的WiFi
WifiInfo info = wifiManager .getConnectionInfo();
1.2得到当前WiFi对象信息,BSSID对应为Mac地址
WiFi对象信息
WiFi定位的原则是最好能获取到附近的几个WiFi热点,然后将几个WiFi进行位置的纠偏。

2.GPS定位

<!-- GPS权限 -->
   <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" />
需要打开手机GPS的位置信息模式为:高精度,这一步很重要,会一直都无法获取到定位信息
模式:高精度
开始定位
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定位失败
}

/**
* 开始请求gps定位
*
* @param locationProvider 参数1,设备:有GPS_PROVIDER和NETWORK_PROVIDER两种,前者是GPS,后者是GPRS以及WIFI定位
* @param minTime  位置信息更新周期.单位是毫秒
* @param minDistance  位置变化最小距离:当位置距离变化超过此值时,将更新位置信息
* 备注:参数2和3,如果参数3不为0,则以参数3为准;参数3为0,则通过时间来定时更新;两者为0,则随时刷新
*/
 private void startRequestLocationUpdates(String locationProvider, long minTime, float minDistance) {
     locationManager.requestLocationUpdates(locationProvider, minTime, minDistance, locationListener);
 }

//监听回调
LocationListener locationListener = new LocationListener() {
           @Override
           public void onLocationChanged(Location location) {
                //位置信息变化时触发,一旦触发这个回调就证明GPS定位成功,这个方法是一直都会回调的,在一定的时间内,需要设置一个超时,以免耗电。
           }
           @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
                switch (status) {
                    case LocationProvider.AVAILABLE:
                       //当前GPS状态为可见状态
                        break;
                    case LocationProvider.OUT_OF_SERVICE:
                       //当前GPS状态为服务区外状态
                        break;
                    case LocationProvider.TEMPORARILY_UNAVAILABLE:
                        //当前GPS状态为暂停服务状态
                        break;
                    default:
                        break;
                }
            }
            @Override
            public void onProviderEnabled(String provider) {
                //GPS开启时触发
            }

            @Override
            public void onProviderDisabled(String provider) {
               //GPS禁用时触发
            }
}
一旦触发onLocationChanged方法就可以得到GPS返回的经纬度,你就可以通过这个经纬去取查询位置啦。点击查询GPS定位(如侵删)
关闭GPS定位
if (locationManager != null) {
  locationManager.removeUpdates(locationListener);
  locationManager = null;
}
if (locationListener != null) {
  locationListener = null;
}

3.基站定位

基站的一些参数说明:
MCC,Mobile Country Code,移动国家代码(中国的为460);
MNC,Mobile Network Code,移动网络号码(中国移动为0,中国联通为1,中国电信为2);
LAC,Location Area Code,位置区域码;
CID,Cell Identity,基站编号;
BSSS,Base station signal strength,基站信号强度。
1.1获取当前手机连接的基站信息
TelephonyManager mTelephonyManager = (TelephonyManager) mContext.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
        if (mTelephonyManager == null) {
            return;
        }
        String operator = mTelephonyManager.getNetworkOperator();
        //获取的基站信息是
        if (operator == null || operator.length() < 5) {
           //获取基站信息有问题,可能是手机没插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) {
            //可能是手机没插sim卡之类的,返回获取基站失败
            return;
        }
//因为移动联通电信基站的不同,所以需要区分基站类型
//中国移动和中国联通获取LAC,CID的方式
if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
           //当前连接的是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);
}
//中国电信获取LAC,CID的方式
if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
            //当前连接是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获取获取附近的基站信息
// 获取邻区基站信息
List<CellInfo> infos = mTelephonyManager.getAllCellInfo();
if(infos==null){
  //没有获取附近任何的基站信息
  return;
}
基站类型的话,也是分为好几种类型的,需要做区分的处理
for (CellInfo i : infos) {
  if (i instanceof CellInfoGsm) {//gsm基站
    Log.i(TAG, "附近发现gsm基站Mcc = " + cellIdentityGsm.getMcc());
    Log.i(TAG, "附近发现gsm基站Mnc = " + cellIdentityGsm.getMnc());
    Log.i(TAG, "附近发现gsm基站Lac = " + cellIdentityGsm.getLac());
    Log.i(TAG, "附近发现gsm基站Cid = " + cellIdentityGsm.getCid());
  }else if (i instanceof CellInfoCdma) {//cdma基站
    Log.i(TAG, "附近发现cdma基站sid = " + cellIdentityCdma.getSystemId());
    Log.i(TAG, "附近发现cdma基站nid = " + cellIdentityCdma.getNetworkId());
    Log.i(TAG, "附近发现cdma基站sid = " + cellIdentityCdma.getBasestationId());
  }else if (i instanceof CellInfoLte) {//lte基站
    Log.i(TAG, "附近发现lte基站Mcc = " + cellIdentityLte.getMcc());
    Log.i(TAG, "附近发现lte基站Mnc = " + cellIdentityLte.getMnc());
    Log.i(TAG, "附近发现lte基站Lac = " + cellIdentityLte.getTac());
    Log.i(TAG, "附近发现lte基站Cid = " + cellIdentityLte.getCi());
  }else if (i instanceof CellInfoWcdma) {//wcdma基站
    Log.i(TAG, "附近发现wcdma基站Mcc = " + cellIdentityWcdma.getMcc());
    Log.i(TAG, "附近发现wcdma基站Mnc = " + cellIdentityWcdma.getMnc());
    Log.i(TAG, "附近发现wcdma基站Lac = " + cellIdentityWcdma.getLac());
    Log.i(TAG, "附近发现wcdma基站Cid = " + cellIdentityWcdma.getCid());
  }
}
以上得到基站信息,即可进行查询点击查询基站定位(如侵删)

相关文章

网友评论

      本文标题:Android的WiFi,GPS,基站定位

      本文链接:https://www.haomeiwen.com/subject/vsmgbqtx.html