基于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. FFM

    转载自http://blog.csdn.net/jediael_lu/ https://blog.csdn.net/jediael_lu/article/details/77772565 点击率预估算 ...

  2. 科普:PCI-E插槽都有哪些样子?

    主板上的扩展插槽曾经是多种多样的,例如曾经非常流行的组合就是PCI插槽搭配AGP插槽,其中AGP插槽主要用在显卡上,而PCI插槽的用途则更广一些,不仅有用在显卡上,还能用于扩展其它设备,如网卡.声卡. ...

  3. Android - TabHost 选项卡功能用法详解

    TabHost效果图 : 源码下载地址 : http://download.csdn.net/detail/han1202012/6845105        . 作者 :万境绝尘  转载请注明出处  ...

  4. "亿家App"问卷调查分析结果及心得体会

    一.问卷问题设计 调查背景:随着现代社会互联网的发展,基于家庭产生的服务项目也越来越多.为增加家庭之间的交流和互助,增加家庭内部.家庭与家庭之间的沟通互助,并利用互联网便捷交流的优势,使家庭在享受服务 ...

  5. centOS6.5如何从启动界面直接进入命令行界面

    进入系统后,按Ctrl+Alt+Fn可以切换控制台,其中F1~F6是字符控制台,F7~F12是X控制台 如果启动直接进入字符控制台,而不是X Window,可以编辑/etc/inittab将id:5: ...

  6. C#中的unsafe

    为了保持类型安全性,默认情况下,C# 不支持指针算法. 但是,通过使用 unsafe 关键字,可以定义可在其中使用指针的不安全上下文. 有关指针的详细信息,请参阅主题指针类型. 备注 在公共语言运行时 ...

  7. java数据结构-HashMap

    一直以来似乎都有一个错觉,认为map跟其他的集合类一样继承自Collection,其实不然,Map和Collection在结构层次上是没有任何关系的,通过查看源码可以发现map所有操作都是基于key- ...

  8. 如何用grep命令同时显示匹配行上下的n行 (美团面试题目)

    标准unix/linux下的grep通过以下参数控制上下文 grep -C 5 foo file 显示file文件中匹配foo字串那行以及上下5行grep -B 5 foo file 显示foo及前5 ...

  9. 使用oledb读取excel表

    string path = "C:\\Users\\aaa\\Desktop\\aa.xls"; string conn = "Provider = Microsoft. ...

  10. bzoj4031-小Z的房间

    题目 给一个\(n\*m\)的矩阵,每个点可能为"."或"*",有多少种方法把矩阵中的点全部连接起来,并且每两个点之间只有一条路径. 分析 题目所求的是一个矩阵 ...