android定位的实现

先抛问题:

  1. locationManager.getLastKnownLocation方法返回null。
  2. 如何实现快速而又精确的定位。

手机定位方案

我们常用的定位一般也就下面这两种发方案:

  • GPS定位
  • 网络定位(基站定位)

最简单的手机定位方式当然是通过GPS模块(现在大部分的智能机应该都有了)。GPS方式准确度是最高的,但是它的缺点也非常明显:

  1. 比较耗电;
  2. 绝大部分用户默认不开启GPS模块;
  3. 从GPS模块启动到获取第一次定位数据,可能需要比较长的时间;
  4. 室内几乎无法使用。

这其中,缺点2,3都是比较致命的。需要指出的是,GPS走的是卫星通信的通道,在没有网络连接的情况下也能用。

另外一种常见的定位方式也就是网络定位了,也就基站定位。大致思路就是采集到手机上的基站ID号(cellid)和其它的一些信息(MNC,MCC,LAC等等),然后通过网络访问一些定位服务,获取并返回对应的经纬度坐标。基站定位的精确度不如GPS,但好处是能够在室内用,只要网络通畅就行。
还有Wifi定位。和基站定位类似,这种方式是通过获取当前所用的wifi的一些信息,然后访问网络上的定位服务以获得经纬度坐标。因为它和基站定位其实都需要使用网络,所以在Android也统称为Network方式。另外,需要指出的是网上相当一部分人说由于国内没有Google服务,无法实现网络定位,这个不敢苟同,用手机基站和WIFI节点的地址来大致定位位置,这种定位方式取决于服务器,即取决于将基站或WIF节点信息翻译成位置信息的服务器的能力。市面上的手机厂商基本在手机系统底部是已经接入国内位置信息服务器的,所以说在国内无法实现网络定位的说法是不存在的。

不多说,来看看一般的实现定位的代码:

LocationManager  mLocationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();  
criteria.setAccuracy(Criteria.ACCURACY_FINE);//高精度  
criteria.setAltitudeRequired(false);//无海拔要求   criteria.setBearingRequired(false);//无方位要求  
criteria.setCostAllowed(true);//允许产生资费   criteria.setPowerRequirement(Criteria.POWER_LOW);//低功耗  
        
// 获取最佳服务对象  
String provider = locationManager.getBestProvider(criteria,true);  
locationManager.getLastKnownLocation(provider);  

locationManager.getBestProvider(criteria,true);方法看起来很完美,但其实返回值就network、gps二选一。而且如果你要求高精度,它会优先检查GPS,如果手机开启了GPS就返回GPS,否则返回network。如果都没开启则返回null。

最要说的就是getLastKnownLocation()方法,首先它获取的是最近一次的定位信息,如果第一次运行呢,当然为空,即使不为空,通过它拿到的位置也未必是实时的位置信息吧。网络定位耗时一般在2秒左右(网络差,时间会更长), 这些都是造成getLastKnownLocation为空的原因,而且如果采取的定位方式是gps,那么90%得到的Location会为空。

那么如果实现尽可能的精准定位呢?

谷歌是有为我们推荐的,可参看:https://developer.android.com/guide/topics/location/strategies.html

思路大概就是通过网络定位和gps定位的结合,来尽可能的获取准确定位,接下来,所要讨论是基于只定位一次的情况下,大部分情况下也确实是这样!

  1. 开启network和gps监听
  2. 获得network定位信息location后,移除network监听
  3. 获得gps定位信息location,移除gps监听
  4. 比较当前location和新获取的location哪个更好(来自gps)

既然结合两者,就要同时为两者添加监听 :

 mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME, MIN_DISTANCE, gpsLocationListener);
        mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME, MIN_DISTANCE, networkListener);

其中MIN_TIME和MIN_DISTANCE根据自己实际情况定义。

网络定位监听器:

 LocationListener networkListener = new LocationListener() {

        @Override
        public void onLocationChanged(Location location) {
            if (isBetterLocation(location, mLocation)) {
                mLocation = location;
            }
            if (mLocation != null) {
                mLocationManager.removeUpdates(this);
            }

        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {
        }

        @Override
        public void onProviderDisabled(String provider) {
        }

    };

gps定位监听器

 LocationListener gpsLocationListener = new LocationListener() {

        @Override
        public void onLocationChanged(Location location) {
            if (isBetterLocation(location, mLocation)) {
                mLocationManager.removeUpdates(networkListener);
                mLocation = location;
            }
            if (mLocation != null) {
                mLocationManager.removeUpdates(this);

            }
        }

        @Override
        public void onProviderDisabled(String provider) {
        }

        @Override
        public void onProviderEnabled(String provider) {
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }
    };

isBetterLocation(Location location, Location currentBestLocation)方法是参考的Google官方提供的,可自行查看.

最后不要忘了要清除监听

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

推荐阅读更多精彩内容