百度地图sdk定位和遇到的坑

封装定位服务类:

import android.content.Context;

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

/**
 * 
 * @author baidu
 *
 */
public class LocationService {
    private LocationClient client = null;
    private LocationClientOption mOption,DIYoption;
    private Object objLock = new Object();

    /***
     * 
     * @param locationContext
     */
    public LocationService(Context locationContext){
        synchronized (objLock) {
            if(client == null){
                client = new LocationClient(locationContext);
                client.setLocOption(getDefaultLocationClientOption());
            }
        }
    }
    
    /***
     * 
     * @param listener
     * @return
     */
    
    public boolean registerListener(BDAbstractLocationListener listener){
        boolean isSuccess = false;
        if(listener != null){
            client.registerLocationListener(listener);
            isSuccess = true;
        }
        return  isSuccess;
    }
    
    public void unregisterListener(BDAbstractLocationListener listener){
        if(listener != null){
            client.unRegisterLocationListener(listener);
        }
    }
    
    /***
     * 
     * @param option
     * @return isSuccessSetOption
     */
    public boolean setLocationOption(LocationClientOption option){
        boolean isSuccess = false;
        if(option != null){
            if(client.isStarted())
                client.stop();
            DIYoption = option;
            client.setLocOption(option);
        }
        return isSuccess;
    }

    /***
     *
     * @return DefaultLocationClientOption  默认O设置
     */
    public LocationClientOption getDefaultLocationClientOption(){
        if(mOption == null){
            mOption = new LocationClientOption();
            //如果使用设备模式(LocationMode.Device_Sensors),只能在线定位,如果断网,回调方法就不会调用,坑。
            //所以只能设置高精度模式
            mOption.setLocationMode(LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备

            mOption.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
            mOption.setScanSpan(5 * 1000);//可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
            mOption.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
            mOption.setIsNeedLocationDescribe(true);//可选,设置是否需要地址描述
            mOption.setNeedDeviceDirect(false);//可选,设置是否需要设备方向结果
            mOption.setLocationNotify(false);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
            mOption.setIgnoreKillProcess(true);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死   
            mOption.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
            mOption.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
            mOption.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集
            mOption.setOpenGps(true);//可选,默认false,设置是否开启Gps定位
            mOption.setIsNeedAltitude(false);//可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用
         
        }
        return mOption;
    }


    /**
     *
     * @return DIYOption 自定义Option设置
     */
    public LocationClientOption getOption(){
        if(DIYoption == null) {
            DIYoption = new LocationClientOption();
        }
        return DIYoption;
    }

    public void start(){
        synchronized (objLock) {
            if(client != null && !client.isStarted()){
                client.start();
            }
        }
    }
    public void stop(){
        synchronized (objLock) {
            if(client != null && client.isStarted()){
                client.stop();
            }
        }
    }

    public boolean isStart() {
        return client.isStarted();
    }

    public boolean requestHotSpotState(){
        return client.requestHotSpotState();
    }
    
}

全局类中onCreate方法中初始化定位服务:

import com.baidu.mapapi.SDKInitializer;


/**
 * 全局应用程序类:用于保存用户信息,和全局应用配置及网络请求等服务初始化
 *
 */
public class AppContext extends Application {

    ... ...

    public LocationService locationService;
    public Vibrator mVibrator;

    /**
     * 获得当前app运行的AppContext
     *
     * @return
     */
    public static AppContext getInstance() {
        return instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        initBaiduSDK();
    }

    private void initBaiduSDK() {
        /***
         * 初始化定位sdk,建议在Application中创建
         */
        locationService = new LocationService(getApplicationContext());
        mVibrator = (Vibrator) getApplicationContext().getSystemService(Service.VIBRATOR_SERVICE);
        SDKInitializer.initialize(getApplicationContext());
    }

}

编写一个Service,后台运行

/*
 * 运行定时上传当前位置服务
 * */
public class UploadLocationService extends Service {

    //60秒上传一次位置
    private static Integer UPLOAD_SECONDS = 20;
    //如果位置不变,大于此秒数后,必须上传当前位置,5分钟必须上传一次
    private static Integer MAX_UPLOAD_SECONDS = 1 * 60;

    private LocationService locationService;

    private static List<PatrolGpsPositionDetailVO> gpsPositionList = new ArrayList<>();
    private static Object lockObj = new Object();
    //定时器
    private Timer timer;
    //最后一次的位置信息
    private static BDLocation lastLocation = null;
    //最后一次上传
    private static Date lastUploadDate = null;

    private static PatrolGpsPositionDetailVO lastGpsPositionVo = null;

    private static Context context = null;

    @Override
    public void onCreate() {
        super.onCreate();
        initBaiduMap();
        
    }

    private void initBaiduMap() {

        locationService = ((AppContext) getApplication()).locationService;

        locationService.registerListener(new BDAbstractLocationListener() {
            @Override
            public void onReceiveLocation(BDLocation location) {
                if (null != location) {
                    writeLocation(location);
                }
            }

            @Override
            public void onConnectHotSpotMessage(String var1, int var2) {
                Log.d("test", "-------onConnectHotSpotMessage----------------------------------------------");
            }

            @Override
            public void onLocDiagnosticMessage(int var1, int var2, String var3) {
                Log.d("test", "-------onLocDiagnosticMessage----------------------------------------------");
            }
        });

        locationService.start();
    }

    private void writeLocation(BDLocation location) {

        StringBuffer sb = new StringBuffer(256);
        sb.append("time : ");
        /**
         * 时间也可以使用systemClock.elapsedRealtime()方法 获取的是自从开机以来,每次回调的时间;
         * location.getTime() 是指服务端出本次结果的时间,如果位置不发生变化,则时间不变
         */
        sb.append(location.getTime());
        sb.append("\nlocType : ");// 定位类型
        sb.append(location.getLocType());
        sb.append("\nlocType description : ");// *****对应的定位类型说明*****
        sb.append(location.getLocTypeDescription());
        sb.append("\nlatitude : ");// 纬度
        sb.append(location.getLatitude());
        sb.append("\nlontitude : ");// 经度
        sb.append(location.getLongitude());
        sb.append("\nradius : ");// 半径
        sb.append(location.getRadius());
        sb.append("\nCountryCode : ");// 国家码
        sb.append(location.getCountryCode());
        sb.append("\nCountry : ");// 国家名称
        sb.append(location.getCountry());
        sb.append("\ncitycode : ");// 城市编码
        sb.append(location.getCityCode());
        sb.append("\ncity : ");// 城市
        sb.append(location.getCity());
        sb.append("\nDistrict : ");//
        sb.append(location.getDistrict());
        sb.append("\nStreet : ");// 街道
        sb.append(location.getStreet());
        sb.append("\naddr : ");// 地址信息
        sb.append(location.getAddrStr());
        sb.append("\nUserIndoorState: ");// *****返回用户室内外判断结果*****
        sb.append(location.getUserIndoorState());
        sb.append("\nDirection(not all devices have value): ");
        sb.append(location.getDirection());// 方向
        sb.append("\nlocationdescribe: ");
        sb.append(location.getLocationDescribe());// 位置语义化信息
        sb.append("\nPoi: ");// POI信息
        if (location.getPoiList() != null && !location.getPoiList().isEmpty()) {
            for (int i = 0; i < location.getPoiList().size(); i++) {
                Poi poi = (Poi) location.getPoiList().get(i);
                sb.append(poi.getName() + ";");
            }
        }
        if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
            sb.append("\nspeed : ");
            sb.append(location.getSpeed());// 速度 单位:km/h
            sb.append("\nsatellite : ");
            sb.append(location.getSatelliteNumber());// 卫星数目
            sb.append("\nheight : ");
            sb.append(location.getAltitude());// 海拔高度 单位:米
            sb.append("\ngps status : ");
            sb.append(location.getGpsAccuracyStatus());// *****gps质量判断*****
            sb.append("\ndescribe : ");
            sb.append("gps定位成功");
        } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
            // 运营商信息
            if (location.hasAltitude()) {// *****如果有海拔高度*****
                sb.append("\nheight : ");
                sb.append(location.getAltitude());// 单位:米
            }
            sb.append("\noperationers : ");// 运营商信息
            sb.append(location.getOperators());
            sb.append("\ndescribe : ");
            sb.append("网络定位成功");
        } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
            sb.append("\ndescribe : ");
            sb.append("离线定位成功,离线定位结果也是有效的");
        } else if (location.getLocType() == BDLocation.TypeServerError) {
            sb.append("\ndescribe : ");
            sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
        } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
            sb.append("\ndescribe : ");
            sb.append("网络不同导致定位失败,请检查网络是否通畅");
        } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
            sb.append("\ndescribe : ");
            sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
        }
        Log.d("location", sb.toString());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("test", "onStartCommand()");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.e("test","service ondestory");
        locationService.stop();
        stopForeground(true);// 停止前台服务--参数:表示是否移除之前的通知
        super.onDestroy();
    }

}

启动或者关闭服务方法,可以在需要时调用,写法如下:

    public static void controlLocationService(Context context, Boolean isStart) {
        Intent intent = new Intent(context, UploadLocationService.class);
        if (isStart) {
            context.startService(intent);
        } else {
            context.stopService(intent);
        }
    }

百度地图和百度定位sdk的坑

1.百度地图zoom大小和对应的长度米的单位如下,zoom为15时,对应的是200米,不是对应500米,要改小,改成14.8才对应500米

public enum BaiduMapZoom {

    //"10m", "20m", "50m", "100m", "200m",
    //"500m", "1km", "2km", "5km", "10km",
    //"20km", "25km", "50km", "100km", "200km"
    //"500km", "1000km", "2000km"
    zoom_20(20,10),
    zoom_19(19,20),
    zoom_18(18,50),
    zoom_17(17,100),
    zoom_16(16,200),

    zoom_15(14.8F,500),
    zoom_14(14,1000),
    zoom_13(13,2000),
    zoom_12(12,5000),
    zoom_11(11,10000),

    zoom_10(10,20000),
    zoom_9(9,25000),
    zoom_8(8,50000),
    zoom_7(7,100000),
    ;

    private float zoom;

    private int unitDistance;

    BaiduMapZoom(float zoom,int unitDistance){
        this.zoom = zoom;
        this.unitDistance = unitDistance;
    }

    public float getZoom() {
        return zoom;
    }

    public void setZoom(int zoom) {
        this.zoom = zoom;
    }

    public int getUnitDistance() {
        return unitDistance;
    }

    public void setUnitDistance(int unitDistance) {
        this.unitDistance = unitDistance;
    }

}

2.地图SDK定位中定位模式有3种,高精度,低功耗,仅设备

建议使用高精度模式,仅设备模式下无法离线定位,出现回调函数不调用的问题。高精度模式下没有此问题,可以离线定位。

mOption.setLocationMode(LocationMode.Hight_Accuracy); //高精度模式

 

posted @ 2018-06-22 11:49  门罗的魔术师  阅读(12502)  评论(0编辑  收藏  举报