百度地图定位 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;