Android的WiFi,GPS,基站定位

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());
  }
}
以上得到基站信息,即可进行查询点击查询基站定位(如侵删)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容