基于android的定位无非就两种:network、gps。两者各有优劣。

Network:定位快,准确度低,受环境影响小。

GPS:定位慢,准确度高,受环境影响大。

本文要解决的问题:

1.      locationManager.getLastKnownLocation方法返回null。

2.      如何实现快速而又精确的定位。

E文好的话,直接看官网就好了http://developer.android.com/guide/topics/location/strategies.html

在你的程序里如果有这样的代码你就要注意了(现在看来这些倒是多余了)

<span style="font-size:14px;">    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); </span>

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

结合Network、GPS两种定位方式的优劣不难看出为什么getLastKnownLocation方法会返回null(这只针对第一次定位)。

当你开启GPS,provider的值为GPS。这时的定位方式为GPS,由于GPS定位慢(我测试的时间大约为50秒),所以它不可能立即返回你一个Location对象,所以就返回null了。还有人用下面的方法解决这个问题:

<span style="font-size:14px;">    while (location ==null) {
location = locationManager.getLastKnownLocation(provider);
} </span>

这绝对是个愚蠢的做法!举个例子:如果你在室内,gps无法定位到,你的程序将陷入死循环。当然使用requestLocationUpdates可以做到定位且不让程序陷入死循环,但是定位耗时长,甚至得不到定位。

如果使用网络定位呢,不得说这也是一个不错的选择。locationManager.requestLocationUpdates(

LocationManager.NETWORK_PROVIDER, 0, 0,networkListener);

网络定位耗时一般在2秒左右(网络差,时间会更长),只要你接入网络,基本上都能获得定位。唯一的缺点就是精度不高。

那能不能将两者结合,这也是本文的重点。既然结合两者,就要同时为两者添加监听

<span style="font-size:14px;">    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000 * 2,50,gpsListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,networkListener); </span>

这样,大概2秒我们就可以得到来自网络的定位,一分钟后得到来自GPS定位。这时用GPS定位替换网络定位就好了。当然这只是个理想的情况,现实要复杂的多。

比如:

你第一次定位成功返回location,由于网络问题第二次返回null。这时会发现,更新的location没有上次的精确,甚至是null,无法使用,这时我们要判断当前的location和新获得的location那个更好。可能你获得GPS定位后,由于天气、进入隧道等原因GPS服务器丢失,无法更新location(这时一个好的做法是切换到network定位)。还有可能用户没有开启GPS和network,根本就谈不上定位(其实每次定位成功都会有个定位缓存的,可以使用getLastKnownLocation获得)。

终上所述,我们要做的就是:

1.  尝试通过getLastKnownLocation获取上次定位信息

2.  开启network和gps监听

3.  获得network定位信息location

4.  比较当前location和新获取的location哪个更好(来自network)

5.  获得gps定位信息location

6.  停掉network监听

7.  比较当前location和新获取的location哪个更好(来自gps)

8.  如果gps服务器丢失,重新开启network监听

以GPS监听为例

<span style="font-size:14px;">    // GPS监听的回调函数
private class GPSLocationListener implements LocationListener { private boolean isRemove = false;//判断网络监听是否移除 @Override
public void onLocationChanged(Location location) {
// TODO Auto-generatedmethod stub
boolean flag =betterLocation.isBetterLocation(location,
currentBestLocation); if (flag) {
currentBestLocation = location;
updateLocation(currentBestLocation);
}
// 获得GPS服务后,移除network监听
if (location !=null && !isRemove) {
locationManager.removeUpdates(networkListener);
isRemove = true;
}
} @Override
public void onProviderDisabled(String provider) {
// TODO Auto-generatedmethod stub
} @Override
public void onProviderEnabled(String provider) {
// TODO Auto-generatedmethod stub
} @Override
public void onStatusChanged(String provider, int status, Bundleextras) {
// TODO Auto-generatedmethod stub
if (LocationProvider.OUT_OF_SERVICE == status) {
Toast.makeText(MainActivity.this,"GPS服务丢失,切换至网络定位",
Toast.LENGTH_SHORT).show();
locationManager
.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0,
networkListener);
}
}
} </span>

其中isBetterLocation是用来判断哪个location更好的。这个方法来自android官网的,通过location获取的时间,精度等信息进行判断。

因为之前上传的demo,大家觉得意义不大,所以就不再提供了。

下图的‘微秒’单位错了,应该是毫秒

后来我接触的项目中对定位的要求发现并不是那么高,只是需要简单的获取到当前位置就够了,而且只是在每次启动时获取一次。

Android简单定位的实现可以参见http://blog.csdn.net/limb99/article/details/18819925

from:http://blog.csdn.net/limb99/article/details/8765584#comments

关注公众号,分享干货,讨论技术

Android之实现定位的更多相关文章

  1. Android 上多方式定位元素(python)

    Android 上多方式定位元素(python) 在学习实际UI自动化测试的时候,首先就需要定位元素,然而定位元素也是最头疼的地方,因为元素各种控件名称的缺失会影响元素的准确定位.下面针对Androi ...

  2. Appium python自动化测试系列之Android UIAutomator终极定位(七)

    android uiautomator text定位 可能有人不知道为什么说android uiautomator是终极定位,而且android uiautomator和appium有什么关系呢?如果 ...

  3. [置顶] xamarin android使用gps定位获取经纬度

    看了文章你会得出以下几个结论 1.android定位主要有四种方式GPS,Network(wifi定位.基站定位),AGPS定位 2.绝大部分android国产手机使用network进行定位是没有作用 ...

  4. XamarinSQLite教程在Xamarin.Android项目中定位数据库文件

    XamarinSQLite教程在Xamarin.Android项目中定位数据库文件 实际开发中,经常需要验证数据库操作的正确性.这个时候,需要打开数据库文件,进行确认.下面是如何找到MyDocumen ...

  5. Android 高德地图定位

    创建Key 打开高德开发平台 → 我的应用 → 创建应用 → 创建新Key 说明: 1.发布版安全码获取:用自己的签名打包成apk安装软件,用SHA1工具查看 2.调试版安全码获取: 直接运行安装软件 ...

  6. Android开发--用户定位服务--UserLocation

    Android开发--用户定位服务--UserLocation 2013-01-28 08:32:26     我来说两句      作者:BruceZhang 收藏    我要投稿 [java] & ...

  7. 我的Android进阶之旅------>Android百度地图定位SDK功能学习

    因为项目需求,需要使用百度地图的定位功能,因此去百度地图开发平台下载了百度地图的Android定位SDK最新版本的开发包和示例代码学习. Android 定位SDK地址:http://develope ...

  8. Appium+python自动化(十二)- Android UIAutomator终极定位凶“胸”器(七)(超详解)

    简介 乍眼一看,小伙伴们觉得这部分其实在异性兄弟那里就做过介绍和分享了,其实不然,上次介绍和分享的大哥是uiautomatorviewer,是一款定位工具.今天介绍的是一个java库,提供执行自动化测 ...

  9. Android apk快速定位、灰色按钮克星--DroidSword

    本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80994434 在进行Android应用程序的逆向分析时,经常需要对Android ...

  10. android studio--百度定位集成001

    安卓现在的大趋势已经是普遍使用androidstudio(安装包[https://yunpan.cn/ckc54idj3JVJb  访问密码 664f])了.这个是集成的一个好的环境. 今天来搞个百度 ...

随机推荐

  1. [转载] RCNN/SPP/FAST RCNN/FASTER RCNN/YOLO/SSD算法简介

    RCNN: RCNN(Regions with CNN features)是将CNN方法应用到目标检测问题上的一个里程碑,由年轻有为的RBG大神提出,借助CNN良好的特征提取和分类性能,通过Regio ...

  2. 使用Response.Write实现在页面的生命周期中前后台的交互

    Response.Write()方法非常的常见,也很普通,就是向http output中输出一string.其输出的内容位于页面的最顶端,常用来实现显示一些页面消息框等逻辑. 一般来说,在页面的整个生 ...

  3. mybatis 枚举类型使用

    一.首先定义接口,提供获取数据库存取的值得方法,如下: public interface BaseEnum { int getCode(); } 二.定义mybatis的typeHandler扩展类, ...

  4. FZU 1844 Earthquake Damage(最大流最小割)

    Problem Description Open Source Tools help earthquake researchers stay a step ahead. Many geological ...

  5. Java中终止正在运行线程

    问题:java 中如何让一个正在运行的线程终止掉? Demo_1: class TT implements Runnable { private boolean flag = true; @Overr ...

  6. lintcode-138-子数组之和

    138-子数组之和 给定一个整数数组,找到和为零的子数组.你的代码应该返回满足要求的子数组的起始位置和结束位置 注意事项 There is at least one subarray that it' ...

  7. 基于gulp的前端自动化开发构建新

    关于gulp的使用,已经在之前写过一篇文章,但是遗留了一个问题.问题是实现文件的增量式更新,就是给html引入的js和css文件打上标记.每次更新标记更新. 上篇文章想通过开发同时实现标记的实时更新, ...

  8. 修改IP的批处理

    昨天遇到一个客户,说是抢火车票来着,用了3个公网IP,要求在抢票前15分钟换次IP(看我这毛病,废话多了,正题) 系统是2003 32位的 因为自己不懂脚本,网上找了个修改了下,就有了下面的脚本: 首 ...

  9. 【MVC】ASP.NET MVC5 使用MiniProfiler 监控MVC性能

    MiniProfiler ,一个简单而有效的迷你剖析器,可以有效的实时监控页面.通过直接引用.Ajax.Iframe形式访问的其它页面进行监控,监控内容包括数据库内容,并可以显示数据库访问的SQL. ...

  10. Python 配置日志的几种方式

    Python配置日志的几种方式 作为开发者,我们可以通过以下3种方式来配置logging: (1)使用Python代码显式的创建loggers,handlers和formatters并分别调用它们的配 ...