最后更新时间:2019年6月17日
功能介绍
百度智能定位服务,是为了帮助广大开发者更好地解决对位置获取的诉求这个难题而开放的服务。百度地图Android定位SDK是为Android移动端应用提供的一套简单易用的定位服务接口,调用接口可获取位置信息,包括经纬度、地址、位置描述等信息。
实现方法
(1)环境配置:申请百度key,下载SDK开发包,创建项目,并配置(导入开发库、添加AK、添加service组件、添加定位权限等);
(2)UI搭建:根据实际需求搭建应用显示界面;
(3)代码实现:调用百度Android SDK提供的接口实现定位功能。
环境配置
1
百度Android SDK提供的所有服务是免费的,使用相关服务功能的一般流程如下:首先注册百度账号用户,然后申请成为百度地图开发者,最后获取服务密钥(AK),即可使用相关服务功能。
移动APP项目创建完成后,进入百度地图开发平台网站,根据应用名称,应用类型、发布版SHA1、开发版SHA1、应用包名等信息生产AK即密钥。详细步骤在此不做介绍,参考百度地图开发平台(https://lbsyun.baidu.com/)中的说明文档。
2
登录百度地图开发平台,选择“开发文档”菜单下“Android定位SDK”子菜单,进入Android定位SDK产品主界面,选择“产品下载”,LBS Android SDK下载中心包含了Android SDK全量定位开发包(即包含基础定位能力、离线定位能力、高精度室内定位能力的开发包),也包含单项定位开发包,开发者结合自身实际需求,自定义下载开发包。同时也可下载开发API文档、示例代码等资源。
3
(1)导入开发库:下载SDK后,将其.jar包、不同CPU架构的.so库导入到工程中。
(2)添加AK:打开AndroidManifest.xml清单文件,在application标签中添加meta-data标签,写入在第1步骤中获取的百度AK,以下为例:
<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="YvduFDB5AwvILu1l5ZuT73eQ6wNVhFTa" > </meta-data>
(3)添加service组件:百度定位SDK提供了定位service服务,需在Application标签中声明,代码如下:
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"></service>
(4)声明资源使用权限:实现定位功能,需为应用程序添加定位使用权限,在AndroidManifest.xml清单文件中添加定位权限声明,以及其他应用程序需要的权限,代码如下:
<!-- 这个权限用于访问GPS定位--> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 这个权限用于进行网络定位--> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 用于读取手机当前的状态--> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 访问网络,网络定位需要上网--> <uses-permission android:name="android.permission.INTERNET" />
百度定位代码实现
在此以MapGIS Mobile提供的地图显示为基础,对接百度定位功能,讲解具体实现方法。百度定位实现可参考高德提供的示例、在线开发指南、API文档。
1
采用MapGIS Mobile SDK实现地图显示,以天地图显示为例。
//获取服务地图对象,其中天地图的默认地图服务类型为MapServer.MAPSERVER_TYPE_TIANDITU MapServer mapServer = ServerLayer.createMapServer(MapServer.MAPSERVER_TYPE_TIANDITU); //设置地图类型 mapServer.setName("Tianditu_vec"); mapServer.setAuthentication("tk", "ad6c6a0bd9b1fa421dfd77ba49e70ecf"); //设置在线url地址 mapServer.setURL("http://t0.tianditu.gov.cn/vec_c/wmts"; ServerLayer mServerLayer = new ServerLayer(); mServerLayer.setMapServer(mapServer); //将服务图层添加到地图对象中 mMap.append(mServerLayer); mapView.setMapAsync(mMap, new MapViewFinishCallback() { @Override public void onDidFinish(boolean success) { if (success) { //地图加载完成 } else { //地图加载失败 } } });
2
初始化定位服务客户端对象,LocationClient是实现定位功能最核心的一个类。
//初始化LocationClient对象 LocationClient mLocationClient = new LocationClient(getApplicationContext());
通过参数配置,可选择定位模式、可设定返回经纬度坐标类型、可设定是单次定位还是连续定位。百度定位SDK所提供的定位模式包括三种:高精度、低功耗和仅用设备定位,开发者可根据自己的实际使用需求进行选择。百度定位SDK返回三种坐标类型的经纬度(国内),分别是GCJ02(国测局坐标)、BD09(百度墨卡托坐标)和BD09ll(百度经纬度坐标)。核心代码如下:
private LocationClientOption getOption(){ if(mOption == null){ mOption = new LocationClientOption(); //可选,默认高精度,设置定位模式,高精度,低功耗,仅设备 mOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy); //可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll; mOption.setCoorType("gcj02"); //可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需大于等于1000ms才有效 mOption.setScanSpan(1000); //可选,设置是否需要地址信息,默认不需要 mOption.setIsNeedAddress(true); //可选,设置是否需要地址描述 mOption.setIsNeedLocationDescribe(true); //可选,设置是否需要设备方向结果 mOption.setNeedDeviceDirect(false); //可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果 mOption.setLocationNotify(false); //可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死 mOption.setIgnoreKillProcess(true); //可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近” mOption.setIsNeedLocationDescribe(true); //可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到 mOption.setIsNeedLocationPoiList(true); //可选,默认false,设置是否收集CRASH信息,默认收集 mOption.SetIgnoreCacheException(false); //可选,默认false,设置是否开启Gps定位 mOption.setOpenGps(true); //可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用 mOption.setIsNeedAltitude(false); } return mOption; } //设置定位参数 locationClient.setLocOption(option);
3
实例化定位监听器,并赋给定位客户端对象,在监听回调中可获取定位相关信息。
//百度定位监听器 private BDAbstractLocationListener mListener = new BDAbstractLocationListener() { @Override public void onReceiveLocation(BDLocation location) { if (null != location && location.getLocType() != BDLocation.TypeServerError) { if (flag) { updateUIView(location); flag = false; } StringBuffer sb = new StringBuffer(256); sb.append("时间 : "); sb.append(location.getTime()); sb.append("\n定位类型 : ");// 定位类型 sb.append(location.getLocType()); sb.append("\n定位类型说明: ");//对应的定位类型说明 sb.append(location.getLocTypeDescription()); sb.append("\n纬度 : ");// 纬度 sb.append(location.getLatitude()); sb.append("\n经度 : ");// 经度 sb.append(location.getLongitude()); sb.append("\n半径 : ");// 半径 sb.append(location.getRadius()); sb.append("\n国家码 : ");// 国家码 sb.append(location.getCountryCode()); sb.append("\n国家名称 : ");// 国家名称 sb.append(location.getCountry()); sb.append("\n城市编码 : ");// 城市编码 sb.append(location.getCityCode()); sb.append("\n城市 : ");// 城市 sb.append(location.getCity()); sb.append("\n区 : ");// 区 sb.append(location.getDistrict()); sb.append("\n区 : ");// 区 sb.append(location.getStreet()); sb.append("\n地址信息 : ");// 地址信息 sb.append(location.getAddrStr()); sb.append("\n用户室内外判断结果: ");//室内外判断结果 sb.append(location.getUserIndoorState()); sb.append("\n方向: ");// 方向 sb.append(location.getDirection()); sb.append("\n位置语义化信息: ");// 位置语义化信息 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("\n速度 : "); sb.append(location.getSpeed());// 速度 单位:km/h sb.append("\n卫星数目 : "); sb.append(location.getSatelliteNumber());// 卫星数目 sb.append("\n海拔高度 : "); sb.append(location.getAltitude());// 海拔高度 单位:米 sb.append("\ngps质量判断 : "); sb.append(location.getGpsAccuracyStatus());// *****gps质量判断***** sb.append("\nGPS定位结果 : "); sb.append("gps定位成功"); } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果 // 运营商信息 if (location.hasAltitude()) {// *****如果有海拔高度***** sb.append("\n海拔 : "); sb.append(location.getAltitude());// 单位:米 } sb.append("\n运营商信息 : ");// 运营商信息 sb.append(location.getOperators()); sb.append("\n网络定位结果 : "); sb.append("网络定位成功"); } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果 sb.append("\n离线定位结果 : "); sb.append("离线定位成功,离线定位结果也是有效的"); } else if (location.getLocType() == BDLocation.TypeServerError) { sb.append("\n离线定位结果 : "); sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因"); } else if (location.getLocType() == BDLocation.TypeNetWorkException) { sb.append("\n离线定位结果 : "); sb.append("网络不同导致定位失败,请检查网络是否通畅"); } else if (location.getLocType() == BDLocation.TypeCriteriaException) { sb.append("\n离线定位结果 : "); sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机"); } textView.setText(sb.toString()); } } }; //设置监听 locationClient.registerLocationListener(locationListener);
4
在定位代码编写完,可以在Activity的onStart生命周期方法中开始定位。
protected void onStart () { super.onStart(); mLocationClient.setLocOption(getOption());//设置定位选项 mLocationClient.registerLocationListener(mListener); //注册监听函数 mLocationClient.start();//开始定位 }
在Activity退出时,可以在onDestroy方法中停止定位。
protected void onDestroy () { super.onDestroy(); mLocationClient.unRegisterLocationListener(mListener); //注销掉监听 mLocationClient.stop(); //停止定位服务 }
5
在上述步骤都完成之后,可调试运行程序查看效果,百度定位的实现效果如下图所示。