美文网首页
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