Android 获取当前地理位置信息

在项目当中经常需要获取当前所在的地理位置信息,但只是单个地位,并不需要地图、周边检索、路线等其他额外的功能,
所以我们如果引入第三方sdk就感觉很笨重,并且有些得不尝试。
           在Android系统中已经为我们提供了简单的获取经纬度的方法,并且也提供了根据经纬度逆地理编码获取当前地理位置信息方法。

一、 首先获取经纬度

1、获取LocationManager位置信息管理对象

LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

2、根据LocationManager获取经纬度提供方式(网络定位、GPS定位) 

  •   Android提供了三种获取经纬度的方式

a: 通过网络定位, 获取方式:LocationManager.NETWORK_PROVIDER 优点:获取精度比较高, 缺点:仅能在户外使用,获取定位信息速度慢,并且耗电高 b: 通过GPS定位 获取方式:LocationManager.GPS_PROVIDER 优点:能在户外户内使用,定位速度快,并且耗电低, 缺点:精确度不高 c: 通过passive定位,非初始化获取位置信息,只用于特定的情景下被动接收位置信息变化,一般不用 获取方式:LocationManager.PASSIVE_PROVIDER


  • 实例代码:
/**
             * 根据LocationManager获取定位信息的提供者
             * @param locationManager
             * @return
             */
            private static String getProvider(LocationManager locationManager){

                //获取位置信息提供者列表
                List<String> providerList = locationManager.getProviders(true);

                if (providerList.contains(LocationManager.NETWORK_PROVIDER)){
                    //获取NETWORK定位
                    return LocationManager.NETWORK_PROVIDER;
                }else if (providerList.contains(LocationManager.GPS_PROVIDER)){
                    //获取GPS定位
                    return LocationManager.GPS_PROVIDER;
                }
                return null;
            }

3、根据经纬度提供者,获取经纬度


代码示例:


public static Location getLocation(Context context) {

                /*获取LocationManager对象*/
                LocationManager locationManager = (LocationManager)   context.getSystemService(Context.LOCATION_SERVICE);
                String provider = getProvider(locationManager);
                if (provider == null) {
                    Toast.makeText(context, "定位失败", Toast.LENGTH_SHORT).show();
                }
                //系统权限检查警告,需要做权限判断
                if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    // TODO: Consider calling ActivityCompat#requestPermissions
                    return null;
                }
                return locationManager.getLastKnownLocation(provider);
            }

 

二、 根据经纬度通过逆地理编码获取位置信息

1、在Android SDK中提供了 Geocoder类来进行位置的解析,

Geocoder在获取位置信息的时候会阻塞主线程,我们在使用的时候,尽量在异步任务中处理位置信息

Geocoder gc =  new Geocoder(this, Locale.getDefault());

在Geocoder中提供了三个方法获取List<Address>位置信息,注意我们获取到的是集合对象

getFromLocation(double latitude, double longitude, int maxResults);
            getFromLocationName(String locationName, int maxResults);
            getFromLocationName(String locationName, int maxResults, double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, double upperRightLongitude);


根据经纬度获取,我们调用getFromLocation方法,如下


Geocoder gc =  new Geocoder(this, Locale.getDefault());
               List<Address>locationList = null;
               try {
                   ocationList = gc.getFromLocation(location.getLatitude(),location.getLongitude(),10);
               } catch (IOException e) {
                   e.printStackTrace();
               }

2、在百度获取高德官网注册应用,调用开放接口获取地理位置信息,这里不在描述

三、对经纬度变化的监听

  • 通过LocationManager设置对位置变化的监听,设置方法如下: locationManager.requestLocationUpdates(); 监听方法如下:
LocationListener locationListener = new LocationListener() {
            //当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发
            public void onLocationChanged(Location location) {
                // log it when the location changes
                if (location != null) {
       	        	checkDistance(location);
       	        }
            }
            // Provider被disable时触发此函数,比如GPS被关闭
                   public void onProviderDisabled(String provider) {
            }
             //  Provider被enable时触发此函数,比如GPS被打开
             public void onProviderEnabled(String provider) {

             }
             // Provider的在可用、暂时不可用和无服务三个状态直接切换时触发此函数
                   public void onStatusChanged(String provider, int status, Bundle extras) {
             }
       };
        private void checkDistance(Location location) {
 		    if (location != null) {
 			    float[] distance = new float[1]; //计算距离
                Location.distanceBetween(location.getLatitude(), location.getLongitude(), store.getLatitude(), store.getLongitude(), distance);
  				float result=(distance[0] / 1000); //km

 		}
 	}

四、权限申请

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />