AMapLocationListener 高德地图定位监听
app内很多地方需要用到定位信息,我就自己封装了一个基于高德地图定位监听的类,以便于获取定位权限,和方便调用定位监听事件。我这边继承了LifecycleObserver,将定位事件和acticity的生命周期绑定在了一起,这样的话即便一开始定位没开或者获取定位失败了,还能在后面继续获取定位信息。
AMapLocationListener
package cn.sunsapp.owner.util;
import android.content.Context;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.maps.model.LatLng;
import com.basic.lattercore.app.Suns;
import com.basic.lattercore.util.permission.PermissionSetting;
import com.yanzhenjie.permission.Action;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.runtime.Permission;
import java.util.List;
public class AMapLocationListener implements LifecycleObserver {
private Context mContext;
public AMapLocationListener(Context context) {
this.mContext = context;
}
private AMapLocationClient locationClient;
//声明mLocationOption对象
private AMapLocationClientOption locationOption = null;
private LatLng myLatlng;
private LocationListener listener;
public void setListener(LocationListener listener) {
this.listener = listener;
}
public LatLng getMyLatlng() {
return myLatlng;
}
private void setMyLatlng(LatLng myLatlng) {
this.myLatlng = myLatlng;
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
void createLocation(){
initLocation();
startLocation();
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
void destroyLocal(){
destroyLocation();
}
private void initLocation() {
//初始化client
locationClient = new AMapLocationClient(Suns.getApplication());
locationOption = getDefaultOption();
//设置定位参数
locationClient.setLocationOption(locationOption);
// 设置定位监听
locationClient.setLocationListener(locationListener);
}
/**
* 默认的定位参数
*/
private AMapLocationClientOption getDefaultOption() {
AMapLocationClientOption mOption = new AMapLocationClientOption();
mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
mOption.setGpsFirst(true);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭
mOption.setHttpTimeOut(30000);//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
mOption.setInterval(5 * 1000);//可选,设置定位间隔。默认为2秒
mOption.setNeedAddress(true);//可选,设置是否返回逆地理地址信息。默认是true
mOption.setOnceLocation(false);//可选,设置是否单次定位。默认是false
mOption.setOnceLocationLatest(false);//可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
mOption.setSensorEnable(false);//可选,设置是否使用传感器。默认是false
mOption.setWifiScan(true); //可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差
mOption.setLocationCacheEnable(true); //可选,设置是否使用缓存定位,默认为true
//mOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.DEFAULT);//可选,设置逆地理信息的语言,默认值为默认语言(根据所在地区选择语言)
return mOption;
}
/**
* 定位监听
*/
com.amap.api.location.AMapLocationListener locationListener = new com.amap.api.location.AMapLocationListener() {
@Override
public void onLocationChanged(AMapLocation location) {
if (null != location) {
StringBuffer sb = new StringBuffer();
//errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
if (location.getErrorCode() == 0) {
double lat = location.getLatitude();
double lon = location.getLongitude();
myLatlng = new LatLng(lat,lon);
setMyLatlng(myLatlng);
if (listener != null) {
listener.success(location);
// 如果需要一直获取定位监听权限的话,就把下面这一行注释掉
locationClient.stopLocation();
}
} else {
//定位失败
sb.append("定位失败" + "\n");
sb.append("错误码:" + location.getErrorCode() + "\n");
sb.append("错误信息:" + location.getErrorInfo() + "\n");
sb.append("错误描述:" + location.getLocationDetail() + "\n");
listener.error();
}
}
}
};
private void startLocation() {
AndPermission.with(mContext)
.runtime()
.permission(Permission.ACCESS_COARSE_LOCATION)
.onGranted(new Action<List<String>>() {
@Override
public void onAction(List<String> data) {
// 启动定位
locationClient.startLocation();
}
}).onDenied(new Action<List<String>>() {
@Override
public void onAction(List<String> data) {
// 获取定位权限弹窗,如果需要每次打开都提示获取定位权限的话,就把下面的判断条件注视打开
// if (AndPermission.hasAlwaysDeniedPermission(mContext, data) ) {
new PermissionSetting(mContext).showSetting(data);
// }
}
}).start();
}
/**
* 销毁定位
*
* @author hongming.wang
* @since 2.8.0
*/
private void destroyLocation() {
if (null != locationClient) {
/**
* 如果AMapLocationClient是在当前Activity实例化的,
* 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
*/
//locationClient.disableBackgroundLocation(true);
locationClient.stopLocation();
locationClient.unRegisterLocationListener(locationListener);
locationClient.onDestroy();
locationClient = null;
locationOption = null;
}
}
public interface LocationListener{
void success(AMapLocation mapLocation);
void error();
}
/**
* 回到自己的定位
*/
// public void moveTolocation(AMap aMap) {
// if (aMap != null && myLatlng != null) {
// //将地图移动到定位点
// aMap.moveCamera(CameraUpdateFactory.changeLatLng(myLatlng));
// }
// }
}
PermissionSetting
package com.basic.lattercore.util.permission;
import android.content.Context;
import android.text.TextUtils;
import com.basic.core.R;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.interfaces.OnConfirmListener;
import com.lxj.xpopup.interfaces.OnInputConfirmListener;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.runtime.Permission;
import java.util.List;
/**
* 用来处理权限一直被拒绝,弹出弹窗让用户去设置界面开启此权限
*/
public class PermissionSetting {
private static final int REQ_CODE_PERMISSION = 1;
private final Context mContext;
public PermissionSetting(Context context) {
this.mContext = context;
}
public void showSetting(final List<String> permissions) {
List<String> permissionNames = Permission.transformText(mContext, permissions);
String message = "我们需要以下权限,请在设置中为我们开启:"+ "\n"+ permissionNames;
new XPopup.Builder(mContext).asConfirm("提示", message,
new OnConfirmListener() {
@Override
public void onConfirm() {
AndPermission.with(mContext)
.runtime()
.setting()
.start(REQ_CODE_PERMISSION);
}
})
.bindLayout(R.layout.my_confim_popup)
.show();
}
}
使用示例(在主页面HomeActivity调用AMapLocationListener)
/**
* 在onCreate()调用即可
*/
private void initLocation() {
//添加定位监听
AMapLocationListener aMapLocationListener = new AMapLocationListener(mContext);
aMapLocationListener.setListener(new AMapLocationListener.LocationListener() {
@Override
public void success(AMapLocation mapLocation) {
// maplocation存放了很多的定位数据,经纬度省市县详细地址都可以从这里拿
}
@Override
public void error() {
}
});
// 将定位监听事件和acitvity生命周期绑定在一起
getLifecycle().addObserver(aMapLocationListener);
}
小结
不同的app都有不同的需求,在AMapLocationClientOption 的getDefaultOption()方法里面设置您所需要的参数。
最后,有啥问题或者我写的有地方写错了希望您能在评论区留言,加个关注点个赞吧,求求您了!