先说说手机定位的方式

1,GPS 绝大部分手机都有GPS模块,这种方式准确度是最高的,但是缺点也很明显,1,耗电高;2,绝大部分用户默认不开启GPS模块。3,从GPS模块启动到获取第一次定位数据,可能需要比较长的时间;4,室内无法使用。需要指出的是,GPS走的是卫星通信的通道,在没有网络连接的情况下也能用。

2,Network方式,基站和wifi定位。这两个方式类似,都是通过采集手机上的基站ID号(cellid)和其他的一些信息,然后通过网络访问一些定位服务,获取并返回定位的经纬度坐标。基站定位精确度不如GPS,但好处是能够在室内用,只要网络通畅就行。

3,最后需要解释一点是AGPS方式,很多人将它和基站定位混为一谈,但其实AGPS的本质仍然是GPS,只是它会使用基站信息对获取GPS进行辅助,然后还能对获取到的GPS结果进行修正,所以AGPS要比传统的GPS更快,准确度略高。

关于GPS模块的开关,

官方的API中,android.provider.Settings.Secure类有2个静态方法:
public static final void setLocationProviderEnabled (ContentResolver cr, String provider, boolean enabled)

public static final boolean isLocationProviderEnabled (ContentResolver cr, String provider)

前面的set方法好像需要其他级别的权限,后者isLocationProviderEnabled 是不需要权限的,所以最佳的方式是读取当前GPS模块的状态,如果为打开,可以提示用户,让其去设置模块开启。当然上面的两个方法是2.2以后的,之前的可以用java反射来调用hide的api

secureClass = cl.loadClass("android.provider.Settings$Secure");
isMethod = secureClass.getMethod("isLocationProviderEnabled",
ContentResolver.class, String.class);
Boolean ret = (Boolean) isMethod.invoke(secureClass, this
.getContentResolver(), "gps");

合理定位方案

Android的官方文档给出了推荐的方案:

首先注册自己的LocationListener,让它同时监听GPS_PROVIDER和NETWORK_PROVIDER;
然后可以调用getLastKnownLocation获得一个Location值,这个值可以作为一个备选值;
然后在一段用户可接受的时间内,不断接收从onLocationChanged返回的位置,并同之前的值做比较,选取其中的最佳;
最后,会剩下一个筛选后的最优结果,你需要判断这个结果是否可接受。如果可以接受,返回给用户,如果不行,告诉用户无法定位。
整个过程你需要定义两个重要的函数:一个是比较两个Location信息,返回其中好的那个;另一个函数则用来判断Location信息是否可以被接受。

概况起来就是,:“快速反应,渐进式精确

具体的类就是LocationManager,

requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener) //来设置监听器。
首先,我们要注意到第1个参数,这个参数的值为2选1,分别是:LocationManager.NETWORK_PROVIDER和LocationManager.GPS_PROVIDER,前者用于移动网络中获取位置,精度较低但速度很快,后者使用GPS进行定位,精度很高但一般需要10-60秒时间才能开始第1次定位,如果是在室内则基本上无法定位。
这2种Provider本质上是互补的,在本教程中,我们会同时开启2个监听,但基于移动网络的监听只会执行一次就会被停止,而基于GPS的监听则会一直持续下去,直至用户自己停止监听。

  1. private class MyLocationListner implements LocationListener{
  2. @Override
  3. public void onLocationChanged(Location location) {
  4. // Called when a new location is found by the location provider.
  5. Log.v("GPSTEST", "Got New Location of provider:"+location.getProvider());
  6. if(currentLocation!=null){
  7. if(isBetterLocation(location, currentLocation)){//isBetterLocation方法来决定一个更佳的location,这里的标准不仅是精度,还有时间标签
  8. Log.v("GPSTEST", "It's a better location");
  9. currentLocation=location;
  10. showLocation(location);
  11. }
  12. else{
  13. Log.v("GPSTEST", "Not very good!");
  14. }
  15. }
  16. else{
  17. Log.v("GPSTEST", "It's first location");
  18. currentLocation=location;
  19. showLocation(location);
  20. }
  21. }
  22. //后3个方法此处不做处理
  23. public void onStatusChanged(String provider, int status, Bundle extras) {
  24. }
  25. public void onProviderEnabled(String provider) {
  26. }
  27. public void onProviderDisabled(String provider) {
  28. }
  29. };

开始监听的片段

  1. private LocationListener gpsListener=null;
  2. private LocationListener networkListner=null;
  3. private void registerLocationListener(){
  4. networkListner=new MyLocationListner();
  5. locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 0, networkListner);
  6. gpsListener=new MyLocationListner();
  7. locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, gpsListener);
  8. }

结束监听

  1. locationManager.removeUpdates(networkListener);

注意权限

<uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/> //精确

<uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/> //粗略定位

下面是具体使用的时候,不确定使用哪种定位方式,可以通过设置标准Criteria来让系统决定使用哪种定位方式,

Criteria可以设置一系列的查询条件,用于查找当前设备当中符合条件的Location Provider
setAccuracy(int accuracy):设置精度(ACCURACY_COARSE, ACCURACY_FINE)
setBearingAccuracy(int accuracy)设置方向的精度(ACCURACY_HIGH, ACCURACY_LOW,ACCURACY_MEDIUM)
setCostAllowed(Boolean costAllowed) 设置找到的Provider是否允许产生费用
setSpeedRequired(Boolean speedRequried) 设置是否需要提供速度
setAltitudeRequired(BooleanaltitudeRequired)  设置是否需要提供海拔信息
setBearingRequired(Boolean bearingRequired)  是否需要方向信息
setHorizontalAccuracy(int accuracy) 设置水平方向的精度(ACCURACY_HIGH,ACCURACY_LOW,ACCURACY_MEDIUM)
setSpeedAccuracy(int accuracy) 设置速度精度
setVerticalAccuracy(int accuracy) 设置垂直方向的精度(ACCURACY_HIGH, ACCURACY_LOW,ACCURACY_MEDIUM)
setPowerRequirement(int level) 设置耗电 NO_REQUIREMENT, POWER_LOW,POWER_HIGH, POWERMEDIUM

  1. Criteria myCri=new Criteria();
  2. myCri.setAccuracy(Criteria.ACCURACY_FINE);//精确度
  3. myCri.setAltitudeRequired(false);//海拔不需要
  4. myCri.setBearingRequired(false);
  5. myCri.setCostAllowed(true);//允许产生现金消费
  6. myCri.setPowerRequirement(Criteria.POWER_LOW);//耗电
  7. String myProvider=locMan.getBestProvider(myCri,true);

public String getBestProvider (Criteria criteria, boolean enabledOnly)

Parameters
criteria    the criteria that need to be matched
enabledOnly    if true then only a provider that is currently enabled is returned
Returns
name of the provider that best matches the requirements

下面是显示出具体的经纬度地址等方法

double latitude=location.getLatitude();//获取纬度
double longitude=location.getLongitude();//获取经度

具体的地址信息需要用到Address和Geocoder类,

Geocoder gc=new Geocoder(context,Locale.CHINA);//Locale是java.util中的一个类
List<Address> listAddress=gc.getFromLocation(latitude,longitude,1);

方法说明,

List<Address>     getFromLocation(double latitude, double longitude, int maxResults)
Returns an array of Addresses that are known to describe the area immediately surrounding the given latitude and longitude.(返回给定经纬值附近的一个Address)

可能一个经纬度会返回多个地址,我们一般需要一个就好。

反过来,也可以通过地址获得经纬度

  1. Geocoder  mygeoCoder=new Geocoder(mContext,Locale.getDefault());
  2. List<Address> lstAddress=mygeoCoder.getFromLocationName(strAddress,1);    //strAddress是输入的地址信息
  3. if(!lstAddress.isEmpty()){
  4.   Address address=lstAddress.get(0);
  5.   double latitude=address.getLatitude()*1E6;
  6.   double longitude=adress.getLongitude()*1E6;
  7.   GeoPoint geopoint=new GeoPoint((int)latitude,(int)longitude);
  8. }

参考:http://www.cnblogs.com/peer/archive/2011/06/01/2065375.html

http://www.learningandroid.net/blog/foundation/tutorial-location-service/

android定位的更多相关文章

  1. android 定位的四种方式

    [原文]  开发中对于地图及地理位置的定位是我们经常要用地,地图功能的使用使得我们应用功能更加完善,下面总结了一下网络中现有对于介绍android定位的4种方式,希望对大家有帮助: android 定 ...

  2. Android定位功能

    不说废话,直接说说实现android定位有关的API吧. 这些API都在android.location包下,一共有三个接口和八个类.它们配合使用即可实现定位功能. 三个接口: GpsStatus.L ...

  3. Android定位功能(二)

    在前文Android定位功能(一)中,已经大致介绍了一下在Android平台中,和定位功能相关的类,并举例获取了位置信息.但是前文是基于Criteria定制了一个标准,通过getBestProvide ...

  4. Android定位测试(深坑)

    问题:我们是一个海外app,市场部去马来西亚打开那边的市场,发现了一个问题,就是我们的app定位有问题,还是成都的定位,主要原因是在马来西亚使用这个app,请求中带的经纬度参数是成都的,导致服务器返回 ...

  5. android 定位的几种方式介绍

    [地理位置] android 定位的几种方式介绍 开发中对于地图及地理位置的定位是我们经常要用地,地图功能的使用使得我们应用功能更加完善,下面 www.androidkaifa.com 总结了一下网络 ...

  6. 六 APPIUM Android 定位方式

    文本转自:http://www.cnblogs.com/sundalian/p/5629500.html APPIUM Android 定位方式   1.定位元素应用元素 1.1通过id定位元素 An ...

  7. 发现最新版百度Android 定位SDK v6.1.3 网络定位bug

    对于百度地图已经实在忍无可忍了,实验室两年以前的一个项目用到了百度地图,以前师兄毕业了,我来维护这个破项目,百度地图推出新版本出来后,老版本的api不能用了,不能做到向下兼容吗?换掉少量的api也就算 ...

  8. Appium学习路—Android定位元素与操作

    一.常用识别元素的工具 uiautomator:Android SDK自带的一个工具,在tools目录下 monitor:Android SDK自带的一个工具,在tools目录下 Appium Ins ...

  9. 目前主流的Android定位有如下几种:

    1.通过GPS模块 GPS方式准确度是最高的,但是它的缺点也非常明显:1,比较耗电:2,绝大部分用户默认不开启GPS模块:3,从GPS模块启动到获取第一次定位数据,可能需要比较长的时间:4,室内几乎无 ...

随机推荐

  1. 解决centos7中python-pip模块不存在的问题

    centos 7中python-pip模块不存在,是因为像centos这类衍生的发行版,源跟新滞后,或者不存在.即使使用yum去search python-pip也找不到软件包. 为了使用安装滞后或源 ...

  2. 设计模式-观察者模式(List列表维护观察者)

    namespace ConsoleApplication1{ interface IObserver { void ReceiveMsg(string msg); } class Observer : ...

  3. linux系统判断是否重启、关机、查询登录诊断分析简介

    Last reboot这个命令是查看每次系统重启的信息 [root@dg01 log]# last rebootreboot system boot 2.6.32-300.10.1. Thu May  ...

  4. easyUI validatebox设置值和获取值,以及属性和方法

    一:表单元素使用easyui时,textbox和validatebox设置值和获取值的方式不一样[转] 1.为text-box设置值只能使用id选择器选择表单元素,只能使用textbox(" ...

  5. LDA(转发)

    主题模型-LDA浅析 分类: 数据挖掘 机器学习2012-09-03 14:09 24937人阅读 评论(16) 收藏 举报 文档allocationsemanticeach算法网络 上个月参加了在北 ...

  6. IT项目管理感悟

    做项目的时候,切记做好需求分析,列出需求清单,需要考虑好每一个细节,一个机柜是否需要PDU,KVM,服务器放置位置,放置几台服务器,服务器是几U的,IP段规划都需要事先规划好,并且文档化.---记住这 ...

  7. squid代理服务器配置详解

    root@proxy squid]# cat squid.conf## Recommended minimum configuration:#visible_hostname www.jd.com # ...

  8. ecshop 获取某个商品的 所有订单信息 或者销量

    把一下代码放到 lib_main.php 1.统计某个下单商品的人数 function get_goods_ordernum($goods_id){ $sql = "select count ...

  9. OSX10.11 删除系统自带的软件

    之前一直用sudo rm - rf 系统的浏览器名字 正常删除safari 升级到10.11后,完全没作用了 需要关闭系统的什么安全模式 csrutil disable 再进入系统使用此命令可正常删除 ...

  10. basePath = request.getScheme()+"://"+request.getServerName()+":"+r

    basePath = request.getScheme()+"://"+request.getServerName()+":"+r (2014-06-30 1 ...