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" />