Android 百度地图定位、显示用户当前位置的工具类

1、构建定位Option的工具类

import com.baidu.location.LocationClientOption;

/**
 * 建造 LocationClientOption 项
 *
 * @author peter  2018-12-21 10:58
 */
public class LocationClientOptionBuilder {
    private LocationClientOption option;

    public static LocationClientOptionBuilder builder() {
        LocationClientOptionBuilder builder = new LocationClientOptionBuilder();
        builder.option = builder.initOption();
        return builder;
    }

    /**
     * 设置坐标系
     *
     * @return
     * @see CoorType
     */
    public LocationClientOptionBuilder setCoorType() {
        return setCoorType(CoorType.bd09ll);
    }

    public LocationClientOptionBuilder setCoorType(CoorType coorType) {
        this.option.setCoorType(coorType.name());
        return this;
    }

    /**
     * 连续定位
     * 可选,设置发起定位请求的间隔,int类型,单位ms
     * 如果设置为0,则代表单次定位,即仅定位一次,默认为0
     * 如果设置非0,需设置1000ms以上才有效
     *
     * @param time
     * @return
     */
    public LocationClientOptionBuilder setScanSpan(int time) {
        this.option.setScanSpan(time);
        return this;
    }

    public LocationClientOption bulid() {
        return this.option;
    }

    private LocationClientOption initOption() {
        LocationClientOption option = new LocationClientOption();
        //可选,设置定位模式,默认高精度
        //LocationMode.Hight_Accuracy:高精度;
        //LocationMode. Battery_Saving:低功耗;
        //LocationMode. Device_Sensors:仅使用设备;
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选,设置返回经纬度坐标类型,默认GCJ02
        //GCJ02:国测局坐标;
        //BD09ll:百度经纬度坐标;
        //BD09:百度墨卡托坐标;
        //海外地区定位,无需设置坐标类型,统一返回WGS84类型坐标
//        option.setCoorType("bd09ll");

        //可选,设置发起定位请求的间隔,int类型,单位ms
        //如果设置为0,则代表单次定位,即仅定位一次,默认为0
        //如果设置非0,需设置1000ms以上才有效
//        option.setScanSpan(1000);

        //可选,设置是否使用gps,默认false
        //使用高精度和仅用设备两种定位模式的,参数必须设置为true
        option.setOpenGps(true);

        //可选,设置是否当GPS有效时按照1S/1次频率输出GPS结果,默认false
//        option.setLocationNotify(true);
        //可选,定位SDK内部是一个service,并放到了独立进程。
        //设置是否在stop的时候杀死这个进程,默认(建议)不杀死,即setIgnoreKillProcess(true)
//        option.setIgnoreKillProcess(true);

        //可选,设置是否收集Crash信息,默认收集,即参数为false
//        option.SetIgnoreCacheException(false);

        //可选,V7.2版本新增能力
        //如果设置了该接口,首次启动定位时,会先判断当前Wi-Fi是否超出有效期,若超出有效期,会先重新扫描Wi-Fi,然后定位
//        option.setWifiCacheTimeOut(5 * 60 * 1000);
        //可选,设置是否需要过滤GPS仿真结果,默认需要,即参数为false
//        option.setEnableSimulateGps(false);
        return option;
    }

    /**
     * 坐标系
     */
    public enum CoorType {
        gcj02,
        bd09,
        bd09ll
    }
}

2、构建定位的工具类

import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;

/**
 * 百度地图定位工具类
 *
 * @author peter  2018-12-21 10:12
 */
public class BMapLocationHelper {

    private static final int LOCATION_SUCCESS = 1;
    static final int LOCATION_FAIL = -1;
    private LocationClient mLocationClient;
    private MyLocationListener myListener = new MyLocationListener();
    private LocationCallBack callBack;


    private BMapLocationHelper(LocationCallBack callBack) {

        this.callBack = callBack;
    }

    public static BMapLocationHelper create(@NonNull Context context, @NonNull LocationClientOption option, @NonNull LocationCallBack callBack) {
        BMapLocationHelper bMapLocationHelper = new BMapLocationHelper(callBack);
        LocationClient client = new LocationClient(context);
        client.setLocOption(option);
        //声明LocationClient类
        client.registerLocationListener(bMapLocationHelper.myListener);
        bMapLocationHelper.mLocationClient = client;
        return bMapLocationHelper;
    }

    /**
     * 开始定位
     */
    public void locStart() {
        mLocationClient.start();
    }

    /**
     * 停止定位
     */
    public void locStop() {
        mLocationClient.stop();
    }

    public void locReStart() {
        mLocationClient.restart();
    }

    public LocationClient getmLocationClient() {
        return mLocationClient;
    }

    /**
     * 地图定位结果监听类
     */
    public class MyLocationListener extends BDAbstractLocationListener {
        private static final String TAG = "MyLocationListener";

        @Override
        public void onReceiveLocation(BDLocation location) {
            if (location == null) return;
            int locType = location.getLocType();
            int status = LOCATION_SUCCESS;
            if (locType != 61 && locType != 161 && locType != 66) status = LOCATION_FAIL;
            String errMsg = getLocationResultMsg(locType);
            callBack.onReceiveLocation(status, location, errMsg);
        }

        @Override
        public void onLocDiagnosticMessage(int i, int i1, String s) {
            Log.i(TAG, "onLocDiagnosticMessage: " + i + "diaType:" + i1);
            callBack.onLocDiagnosticMessage(i, i1, getLocDiagnosticMessage(i, i1));
            super.onLocDiagnosticMessage(i, i1, s);
        }
    }


    /**
     * 回调类
     */
    public abstract static class LocationCallBack {

        /**
         * 定位的结果
         *
         * @param statusCode 状态码,1:定位成功,-1定位失败
         * @param bdLocation 定位成功时返回的定位结果对象
         * @param errMsg     定位失败时的错误信息,成功时则为null
         */
        public abstract void onReceiveLocation(int statusCode, BDLocation bdLocation, String errMsg);

        /**
         * 错误的状态码
         * <a>http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/addition-func/error-code</a>
         * <p>
         * 回调定位诊断信息,开发者可以根据相关信息解决定位遇到的一些问题
         *
         * @param locType           当前定位类型
         * @param diagnosticType    诊断类型(1~9)
         * @param diagnosticMessage 具体的诊断信息释义
         */
        public void onLocDiagnosticMessage(int locType, int diagnosticType, String diagnosticMessage) {
        }
    }

    /**
     * 错误的状态码
     * <a>http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/addition-func/error-code</a>
     *
     * @param locType 当前定位类型
     * @return String 定位成功或失败的信息
     */
    private String getLocationResultMsg(int locType) {
        switch (locType) {
            case 61:
                return "GPS定位结果,GPS定位成功";
            case 62:
                return "无法获取有效定位依据,定位失败,请检查运营商网络或者WiFi网络是否正常开启,尝试重新请求定位";
            case 63:
                return "网络异常,没有成功向服务器发起请求,请确认当前测试手机网络是否通畅,尝试重新请求定位";
            case 66:
                return "离线定位结果。通过requestOfflineLocaiton调用时对应的返回结果";
            case 67:
                return "离线定位失败";
            case 161:
                return "网络定位结果,网络定位成功";
            case 162:
                return "请求串密文解析失败,一般是由于客户端SO文件加载失败造成,请严格参照开发指南或demo开发,放入对应SO文件";
            case 167:
                return "服务端定位失败,请您检查是否禁用获取位置信息权限,尝试重新请求定位";
            case 505:
                return "AK不存在或者非法,请按照说明文档重新申请AK";
            default:
                return "";
        }
    }

    /**
     * @param locType        当前定位类型
     * @param diagnosticType 诊断类型(1~9)
     * @return String
     */
    private String getLocDiagnosticMessage(int locType, int diagnosticType) {

        switch (locType) {
            case 62:
                switch (diagnosticType) {
                    case 4:
                        return "定位失败,无法获取任何有效定位依据";
                    case 5:
                        return "定位失败,无法获取有效定位依据,请检查运营商网络或者Wi-Fi网络是否正常开启,尝试重新请求定位";
                    case 6:
                        return "定位失败,无法获取有效定位依据,请尝试插入一张sim卡或打开Wi-Fi重试";
                    case 7:
                        return "定位失败,飞行模式下无法获取有效定位依据,请关闭飞行模式重试";
                    case 9:
                        return "定位失败,无法获取任何有效定位依据";
                }
            case 67:
                if (diagnosticType == 3) return "定位失败,请您检查您的网络状态";

            case 161:
                switch (diagnosticType) {
                    case 1:
                        return "定位失败,建议您打开GPS";
                    case 2:
                        return "定位失败,建议您打开Wi-Fi";
                }
            case 167:
                if (diagnosticType == 8) return "定位失败,请确认您定位的开关打开状态,是否赋予APP定位权限";

            default:
                return "未知错误";
        }
    }
}

3、显示用户当前位置到地图的工具类

import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;

import com.baidu.location.BDLocation;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.yikesong.sender.util.ToastUtils;

/**
 * 显示用户当前位置到地图上
 *
 * @author peter  2018-12-21 16:27
 */
public class UserLocation extends BMapLocationHelper.LocationCallBack {
    private Context context;
    private boolean isFirstLoc = true;
    private BaiduMap map;
    private int mCurrentDirection = 0;
    private BMapLocationHelper helper;
    private static final String TAG = "UserLocation";

    public UserLocation(@NonNull Context context, @NonNull BaiduMap map) {
        this.context = context;
        this.map = map;
        init();
    }

    private void init() {
        map.setMapType(BaiduMap.MAP_TYPE_NORMAL);
        //开启定位图层
        map.setMyLocationEnabled(true);
    }

    /**
     * 在地图上显示用户的当前位置
     */
    public void showUserLocationOnMap() {
        if (helper == null) {
            LocationClientOption option = LocationClientOptionBuilder
                    .builder()
                    .setCoorType()
                    .bulid();
            helper = BMapLocationHelper.create(this.context, option, this);
        }
        helper.locStart();
    }

    @Override
    public void onReceiveLocation(int statusCode, BDLocation bdLocation, String errMsg) {
        if (statusCode == BMapLocationHelper.LOCATION_FAIL) {
            ToastUtils.toastInfo(errMsg, context);
            Log.i(TAG, "onReceiveLocation: " + errMsg);
            return;
        }
        MyLocationData locData = new MyLocationData.Builder()
                .accuracy(bdLocation.getRadius())
                // 此处设置开发者获取到的方向信息,顺时针0-360
                .direction(mCurrentDirection).latitude(bdLocation.getLatitude())
                .longitude(bdLocation.getLongitude()).build();
        map.setMyLocationData(locData);
        if (isFirstLoc) {
            isFirstLoc = false;
            LatLng centerPoint = new LatLng(bdLocation.getLatitude(),
                    bdLocation.getLongitude());
            MapStatus mapStatus = new MapStatus.Builder()
                    .target(centerPoint) //设置中心点
                    .zoom(18f)//设置缩放级别
                    .build();
            map.animateMapStatus(MapStatusUpdateFactory.newMapStatus(mapStatus));
        }
        if (helper != null) helper.locStop();
    }

    @Override
    public void onLocDiagnosticMessage(int locType, int diagnosticType, String diagnosticMessage) {
        super.onLocDiagnosticMessage(locType, diagnosticType, diagnosticMessage);
    }

    public BMapLocationHelper getHelper() {
        return helper;
    }

    public BaiduMap getMap() {
        return map;
    }

    public int getmCurrentDirection() {
        return mCurrentDirection;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值