android 7.0 百度地图定位总结 手机硬件-android 4.4升级到7.0

百度地图定位 sdk升级 手机7.0

本博客内容:

  • 项目背景
  • 问题罗列和解决思路
  • 百度地图 定位权限问题
  • 百度地图最简demo

一、项目背景

原来老项目,维护,发现sdk有些api不能用了;方法过时;
再加上原来,手机不是6.0没有考虑权限问题,这时候,在7.0上就包错了,项目需要定位权限,手机状态权限,网络权限、存储权限等;
原来的定位思路和现在也同了,还发现一些奇奇怪怪的问题,总结如下。

二、问题罗列和解决思路

1.开启定位,关闭定位,思路新老不同,当然用新的;

开启关闭用的mLocClient;

 /**
     * 开启定位
     *
     * @param ScanSpan 定位返回信息时间间隔
     */
    public void startLocation(int ScanSpan, UpdateMapListener listener) {
        /*********************************老定位方法 atart***********************************************/
//        // 定位初始化
//        mLocClient = new LocationClient(this);
//        mLocClient.registerLocationListener(new MyAbstractLocationListenner(this, listener));
//        if (option==null){
//            option = new LocationClientOption();
//            option.setOpenGps(true);// 打开gps
//            option.setCoorType("bd09ll"); // 设置坐标类型
//            option.setLocationNotify(true);// 可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
//            option.setScanSpan(ScanSpan);// 默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1
//            option.setLocationMode(com.baidu.location.LocationClientOption.LocationMode.Hight_Accuracy);// 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
//            option.setIsNeedAddress(true);// 可选,设置是否需要地址信息,默认不需要
//            option.setIgnoreKillProcess(true);// 可选,默认false,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认杀死
//            option.setProdName("shanhong");
//        }
//        mLocClient.setLocOption(option);
//        mLocClient.start();
        /*********************************老定位方法 end***********************************************/
        /*********************************新定位方法 start***********************************************/

        mListener = new MyAbstractLocationListenner(this, listener);
        locationServiceUtil.registerListener(mListener);
        LocationClientOption mOption = locationServiceUtil.getDefaultLocationClientOption();
        mOption.setScanSpan(ScanSpan);// 默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1
        locationServiceUtil.setLocationOption(mOption);
        locationServiceUtil.start();//开启
        /*********************************新定位方法 end***********************************************/

    }

新的定位,写了一个定位服务,其是不是服务,就是一个工具类;
采用同步代码块,对client做了比较好的控制;

/**
 * 百度官方定位服务类
 * @author baidu
 *
 */
public class LocationServiceUtil {
    private LocationClient client = null;
    private LocationClientOption mOption,DIYoption;
    private Object objLock = new Object();

    /***
     *
     * @param locationContext
     */
    public LocationServiceUtil(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();
            mOption.setLocationMode(LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
            mOption.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
            mOption.setScanSpan(3000);//可选,默认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();
    }

}

在项目中使用时,第一步在application中初始化;

 locationServiceUtil = new LocationServiceUtil(context);//定位工具
        // 在使用 SDK 各组间之前初始化百度地图 context 信息,传入 ApplicationContext
        SDKInitializer.initialize(this);

第二步,新建监听;原来一个listener过时了,现在都用这个
public abstract class BDAbstractLocationListener
extends java.lang.Object

最新版本新增的定位信息回调abstract类,开发者可以选择性实现其中的功能

  private LocationDao dao;
    private LocationDB lDB;
    private BDAbstractLocationListener listenner = new BDAbstractLocationListener() {
        @Override
        public void onReceiveLocation(BDLocation location) {
            LogUtil.e("sjt", "欢迎页 获得到位置,定位类型:" + location.getLocType());

            if (location != null) {
                lDB = new LocationDB();
                lDB.LTTD = String.valueOf(location.getLatitude());
                lDB.LGTD = String.valueOf(location.getLongitude());
                lDB.createTime = lDB.id = UtilTime.getLongDate();
                if (dao == null && mContext != null) {
                    //dao = new LocationDao(application.getApplicationContext());
                    dao = new LocationDao(mContext);
                }
                dao.save(lDB);
                lDB = dao.getTopModel();

                if (application != null) {
                    application.setLocation(location);
                    Constant.lat = location.getLatitude();
                    Constant.lon = location.getLongitude();
                    LogUtil.e("sjt", "splash 定位监听-定位成功,保存定位信息");
                }
            }
            application.locationServiceUtil.unregisterListener(listenner);
            application.locationServiceUtil.stop();
            init();
        }
    };

第三步在开启定位的地方用:

  application.locationServiceUtil.registerListener(listenner);
        application.locationServiceUtil.getDefaultLocationClientOption().setScanSpan(0);
        application.locationServiceUtil.start();

2.在fragment里,用百度地图时,发现getBaiduMap为null

具体解决,我发到百度地图论坛了:
见链接:
http://bbs.lbsyun.baidu.com/forum.php?mod=viewthread&tid=15662
本人用的普通fragment,没用那个supportMapFragment;
只要getbaidumap,在oncreatview后就行;我放到onresume了;
我的手机是android 7.0;最新的sdk;base——4.5.2 so包;

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
      view = inflater.inflate(R.layout.fragment_patrol_path, null);
        ViewUtils.inject(this, view);
        // 初始化地图
        try {
            mMapView = (MapView) view.findViewById(R.id.bmapView);
            //mMapView.removeViewAt(1);
            if (application == null) {
                application = CommApplication.getInstance();
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return view;
    }

    @Override
    public void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        mMapView.onResume();
        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(14.0f);
        mBaiduMap = mMapView.getMap();
        BDLocation location=application.getLocation();
        if (location!=null&&mBaiduMap!=null){
            msu = MapStatusUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude()));
            mBaiduMap.setMapStatus(msu);
            mMapView.showZoomControls(false);
        }
        initData();
    }

三、定位权限问题

前面讲了百度如何定位,现在说,打开地图定位权限,为了适配7.0手机;
我用的张鸿阳的MP,使用见链接:
https://github.com/hongyangAndroid/MPermissions
开启定位权限,声明一个码;
private static final int REQUEST_LOCATION = 8;//地图定位码


  //定位权限      MPermissions.requestPermissions(SplashActivity.this, REQUEST_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION);
        MPermissions.requestPermissions(SplashActivity.this, REQUEST_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION);

使用时需要重写几个方法,定位允许,定位拒绝的方法;

 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        MPermissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
  @PermissionGrant(REQUEST_LOCATION)
    public void requestLocationSuccess() {
        LogUtil.e("sjt", "欢迎页--获得手机定位权限");     application.locationServiceUtil.registerListener(listenner);
        application.locationServiceUtil.getDefaultLocationClientOption().setScanSpan(0);
        application.locationServiceUtil.start();

    }

    @PermissionDenied(REQUEST_LOCATION)
    public void requestLocationFailed() {
        showToast(getString(R.string.request_location_deny));
    }

四、 demo下载

我整理一下,传一个简单demo,到github;

猜你喜欢

转载自blog.csdn.net/u014624241/article/details/78983840