• android定位


    先说说手机定位的方式

    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的监听则会一直持续下去,直至用户自己停止监听。

    [java] view plaincopy
     
    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.    
    23.     //后3个方法此处不做处理  
    24.     public void onStatusChanged(String provider, int status, Bundle extras) {  
    25.     }  
    26.    
    27.     public void onProviderEnabled(String provider) {  
    28.     }  
    29.    
    30.     public void onProviderDisabled(String provider) {  
    31.     }  
    32. };  

    开始监听的片段

    [java] view plaincopy
     
    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.     }  

    结束监听

    [java] view plaincopy
     
    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

    [java] view plaincopy
     
    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)

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

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

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



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

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

    路漫漫其修远兮 吾将上下而求索
  • 相关阅读:
    C# 日期格式化
    MVVM框架下,WPF实现Datagrid里的全选和选择
    【转】WPF 给DataGridTextColumn统一加上ToolTip
    C# 获取当前月第一天和最后一天 计算两个日期差多少天
    WPF 弹出UserControl
    斐讯Fir302b救砖教程
    mvc 传递匿名对象
    Java HttpGet
    Java xml object 互转
    HttpClientHandler
  • 原文地址:https://www.cnblogs.com/hudabing/p/4025974.html
Copyright © 2020-2023  润新知