Android之实现定位
基于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之实现定位的更多相关文章
- Android 上多方式定位元素(python)
Android 上多方式定位元素(python) 在学习实际UI自动化测试的时候,首先就需要定位元素,然而定位元素也是最头疼的地方,因为元素各种控件名称的缺失会影响元素的准确定位.下面针对Androi ...
- Appium python自动化测试系列之Android UIAutomator终极定位(七)
android uiautomator text定位 可能有人不知道为什么说android uiautomator是终极定位,而且android uiautomator和appium有什么关系呢?如果 ...
- [置顶]
xamarin android使用gps定位获取经纬度
看了文章你会得出以下几个结论 1.android定位主要有四种方式GPS,Network(wifi定位.基站定位),AGPS定位 2.绝大部分android国产手机使用network进行定位是没有作用 ...
- XamarinSQLite教程在Xamarin.Android项目中定位数据库文件
XamarinSQLite教程在Xamarin.Android项目中定位数据库文件 实际开发中,经常需要验证数据库操作的正确性.这个时候,需要打开数据库文件,进行确认.下面是如何找到MyDocumen ...
- Android 高德地图定位
创建Key 打开高德开发平台 → 我的应用 → 创建应用 → 创建新Key 说明: 1.发布版安全码获取:用自己的签名打包成apk安装软件,用SHA1工具查看 2.调试版安全码获取: 直接运行安装软件 ...
- Android开发--用户定位服务--UserLocation
Android开发--用户定位服务--UserLocation 2013-01-28 08:32:26 我来说两句 作者:BruceZhang 收藏 我要投稿 [java] & ...
- 我的Android进阶之旅------>Android百度地图定位SDK功能学习
因为项目需求,需要使用百度地图的定位功能,因此去百度地图开发平台下载了百度地图的Android定位SDK最新版本的开发包和示例代码学习. Android 定位SDK地址:http://develope ...
- Appium+python自动化(十二)- Android UIAutomator终极定位凶“胸”器(七)(超详解)
简介 乍眼一看,小伙伴们觉得这部分其实在异性兄弟那里就做过介绍和分享了,其实不然,上次介绍和分享的大哥是uiautomatorviewer,是一款定位工具.今天介绍的是一个java库,提供执行自动化测 ...
- Android apk快速定位、灰色按钮克星--DroidSword
本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80994434 在进行Android应用程序的逆向分析时,经常需要对Android ...
- android studio--百度定位集成001
安卓现在的大趋势已经是普遍使用androidstudio(安装包[https://yunpan.cn/ckc54idj3JVJb 访问密码 664f])了.这个是集成的一个好的环境. 今天来搞个百度 ...
随机推荐
- solidity 十六进制字符串转十六进制bytes
pragma solidity ^0.4.16; contract Metadata { // 十六进制字符串转换成bytes function hexStr2bytes(string data)re ...
- 十一:Centralized Cache Management in HDFS 集中缓存管理
集中的HDFS缓存管理,该机制可以让用户缓存特定的hdfs路径,这些块缓存在堆外内存中.namenode指导datanode完成这个工作. Centralized cache management i ...
- es6从零学习(二):promise
es6从零学习(二):promise 一:promise的由来 某些情况下,回调嵌套很多时,代码就会非常繁琐,会给我们的编程带来很多的麻烦,这种情况俗称——回调地狱.由此,Promise的概念就由社区 ...
- II 3.1 连接到服务器
II 3.1 连接到服务器 package socket; import java.io.IOException; import java.io.InputStream; import java.ne ...
- error : Web 项目“RealEstate.Web”的 URL“http://localhost:20000”已配置为将 IIS 用作 Web 服务器,但是当前在 IIS Express W
error : Web 项目"RealEstate.Web"的 URL"http://localhost:20000"已配置为将 IIS 用作 Web 服务器 ...
- C# Dsoframer.ocx 如何在winform中嵌入Excel,内嵌Excel,word
如果你还不太清楚Dspframer.ocx怎么放到窗体上就看上一篇文章,里面详细介绍了是如何放到窗体上的. 链接:http://www.cnblogs.com/pingming/p/4182045.h ...
- MindManager2018 修改过期时间 配置文件路径
路径:C:\Users\likui\AppData\Roaming\MindManager\MindManager2018.ini 文件中记录了安装时间和最后一次启动时间. [MindManager] ...
- 从大量的IP访问记录中找到访问次数最多的IP
1.内存不受限 一个IP有32bit(4Byte),1GB=10亿,那么在4GB内存的情况下,可以存10亿个IP.用HashMap,边存入IP边维护一个最大次数,这样遍历一遍就可以求出,时间复杂度为O ...
- cacti 添加mysql 监控 (远程服务器)
监控主机 192.168.24.69 ,以下用A表示 被监控主机 192.168.24.79,以下用B标识 记得在A服务器的cacti中导入监控mysql的templates文件 1.在B上安 ...
- 主流 Kubernetes 发行版梳理
2014 年,Kubernetes 作为内部 Google orchestrator Borg 开源版本推出,目前已是最成功和发展最快的 IT 基础架构项目之一.2018 年,Kubernetes 已 ...