百度地图SDK Android版开发 3 显示定位
前言
本文主要介绍百度地图显示定位相关的功能和接口,以及使用方法。
要在地图中显示定位,主要有两个步骤:
- 获取定位数据。
- 将定位数据在地图中显示。
本文先介绍定位数据包括哪些内容,如何在地图中显示定位,最后简单介绍下如何获取定位数据。
显示定位
定位数据
百度地图定义了MyLocationData
定位数据类,通过MyLocationData.Builder
定位数据建造器构建。
类图
通过经纬度创建一个定位数据
MyLocationData data = new MyLocationData.Builder()
.latitude(latitude)
.longitude(longitude)
.build();
定位配置信息
百度地图SDK支持三种定位模式,并支持自定义样式。
定位模式
MyLocationConfiguration.LocationMode
定义了三种定位模式
- NORMAL(普通态)
- FOLLOWING(跟随态)
- COMPASS(罗盘态)
定位配置信息
百度地图定义了MyLocationConfiguration
定位图层配置信息类,通过MyLocationConfiguration.Build
构建。类图如下:
创建一个普通态配置信息
// 设置定位图层配置信息:普通态模式, 不显示箭头
MyLocationConfiguration config = new Builder(LocationMode.NORMAL, false).build();
显示定位接口
BaiduMap
类中有三个接口用于定位的显示,
- 设置是否允许定位图层。
- 设置定位图层配置信息。
- 设置定位数据。
类图
接口
类型 | 方法 | 说明 |
---|---|---|
void | setMyLocationEnabled(boolean enabled) | 设置是否允许定位图层 |
void | setMyLocationConfiguration(MyLocationConfiguration configuration) | 设置定位图层配置信息。 只有先允许定位图层后设置才会生效。 |
void | setMyLocationData(MyLocationData data) | 设置定位数据。 只有先允许定位图层后设置才会生效。 |
MapLocationSimple类
创建一个简单的地图定位类,将上述定位数据和定位配置信息传递给地图类。MapLocationSimple
类主要包括以下功能:
- 地图加载完成时,设置定位图层配置信息。
- 地图销毁时,关闭定位图层。
- 设置定位图层的开启和关闭。
- 设置位置坐标。
- 更新位置信息。
完整代码如下:
package com.example.baidudemo;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;
import com.baidu.mapapi.map.MyLocationConfiguration.Builder;
import com.baidu.mapapi.map.MyLocationData;
public class MapLocationSimple {
private final BaiduMap map;
private double latitude = 0.0;
private double longitude = 0.0;
public MapLocationSimple(MapView mapView) {
map = mapView.getMap();
}
/**
* 地图加载完成时,设置定位图层配置信息
*/
public void onMapLoaded() {
// 设置定位图层配置信息:普通态, 不显示箭头
MyLocationConfiguration config = new Builder(LocationMode.NORMAL, false)
.build();
map.setMyLocationConfiguration(config);
}
/**
* 地图销毁时,关闭定位图层
*/
public void onMapDestroy() {
// 关闭定位图层
map.setMyLocationEnabled(false);
}
/**
* 设置定位图层的开启和关闭
*/
public void setLocationEnabled(boolean enabled) {
if (enabled) {
map.setMyLocationEnabled(true);
updateLocation();
} else {
map.setMyLocationEnabled(false);
}
}
/**
* 设置位置坐标
* @param latitude 纬度
* @param longitude 经度
*/
public void setLocation(double latitude, double longitude) {
this.latitude = latitude;
this.longitude = longitude;
updateLocation();
}
/**
* 更新位置信息
*/
private void updateLocation() {
MyLocationData data = new MyLocationData.Builder()
.latitude(latitude)
.longitude(longitude)
.build();
// 设置定位数据
map.setMyLocationData(data);
}
}
模拟定位显示
- 地图加载完成时,开启定位图层并设置模拟位置。
- 地图视图销毁时,关闭定位图层。
部分代码如下:
public class MainActivity extends AppCompatActivity {
private MapView mapView;
private MapLocationSimple mapLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.bmapView);
mapView.getMap().setOnMapLoadedCallback(new MapLoadedCallBack());
mapLocation = new MapLocationSimple(mapView);
}
/**
* 自定义地图加载完成回调接口
*/
private class MapLoadedCallBack implements BaiduMap.OnMapLoadedCallback {
@Override
public void onMapLoaded() {
// 开启定位图层
mapLocation.setLocationEnabled(true);
// 地图加载完成
mapLocation.onMapLoaded();
// 设置模拟位置
setSimulateLocation();
}
}
/**
* 设置模拟位置
*/
private void setSimulateLocation() {
// 模拟定位位置
double latitude = 39.923615;
double longitude = 116.49094;
// 转换为百度坐标
// 初始化坐标转换工具类,指定源坐标类型和坐标数据
LatLng sourceLatLng = new LatLng(latitude, longitude);
// sourceLatLng待转换坐标
CoordinateConverter converter = new CoordinateConverter()
.from(CoordinateConverter.CoordType.GPS)
.coord(sourceLatLng);
// desLatLng 转换后的坐标
LatLng destLatLng = converter.convert();
// 设置位置
mapLocation.setLocation(destLatLng.latitude, destLatLng.longitude);
// 以动画方式更新地图状态
MapStatus.Builder builder = new MapStatus.Builder();
builder.target(destLatLng).zoom(14.0f);
mapView.getMap().animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapLocation.onMapDestroy();
mapView.onDestroy();
mapView = null;
}
}
效果图
获取定位
配置地图+定位开发包
百度地图下载SDK时,默认不会包含定位功能。若要获取定位数据,需确保开发包中包含基本定位功能。
以基础定位为例,将下载的地图包解压,拷贝至app/libs
目录。
app/libs
├── BaiduLBS_Android.aar
├── arm64-v8a
│ ├── libBaiduMapSDK_base_v7_6_2.so
│ ├── libBaiduMapSDK_map_v7_6_2.so
│ ├── libc++_shared.so
│ ├── liblocSDK8b.so
│ └── libtiny_magic.so
├── armeabi-v7a
│ ├── libBaiduMapSDK_base_v7_6_2.so
│ ├── libBaiduMapSDK_map_v7_6_2.so
│ ├── libc++_shared.so
│ ├── liblocSDK8b.so
│ └── libtiny_magic.so
├── x86
│ ├── libBaiduMapSDK_base_v7_6_2.so
│ ├── libBaiduMapSDK_map_v7_6_2.so
│ ├── libc++_shared.so
│ ├── liblocSDK8b.so
│ └── libtiny_magic.so
└── x86_64
├── libBaiduMapSDK_base_v7_6_2.so
├── libBaiduMapSDK_map_v7_6_2.so
├── libc++_shared.so
├── liblocSDK8b.so
└── libtiny_magic.so
定位服务
- 文件
AndroidManifest.xml
,application
标签中,声明定位的service组件。 - 每个App拥有自己单独的定位service。
<application>
<service android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote"/>
</application>
定位权限
- 文件
AndroidManifest.xml
,manifest
标签中添加定位权限。
<manifest>
<!-- 这个权限用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 这个权限用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 获取网络状态,根据网络状态切换进行数据请求网络转换 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
注意需动态申请的权限。
隐私合规接口
百度Android定位SDK自v9.2.9版本起增加了隐私合规接口,请务必确保用户同意隐私政策后调用setAgreePrivacy接口,以进行SDK初始化之前的准备工作。
新增定位SDK隐私合规接口setAgreePrivacy(boolean isAgreePrivacy);
// setAgreePrivacy接口需要在LocationClient实例化之前调用
// 如果setAgreePrivacy接口参数设置为了false,则定位功能不会实现
// true,表示用户同意隐私合规政策
// false,表示用户不同意隐私合规政策
LocationClient.setAgreePrivacy(true);
定位服务
获取定位关键的两个类LocationClient
和BDAbstractLocationListener
和生命周期管理。
- 通过
LocationClient
发起定位。 - 通过继承抽象类
BDAbstractLocationListener
并重写其onReceiveLocation
方法来获取定位数据,并将其传给MapView。 - 在销毁地图时停止定位。
类 | 说明 |
---|---|
LocationClient | 定位服务的客户端,宿主程序在客户端声明此类,并调用,目前只支持在主线程中启动 |
BDAbstractLocationListener | 新版本定位请求回调接口 |
部分示例代码
private LocationClient client;
private MyLocationListener myListener = new MyLocationListener();
/**
* 定位SDK监听函数
*/
public class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// MapView 销毁后不在处理新接收的位置
if (location == null || mapView == null) {
return;
}
setLocation(location.getLatitude(), location.getLongitude());
updateLocation();
}
}
发起定位
// 定位SDK隐私合规
LocationClient.setAgreePrivacy(true);
// 定位初始化
// 实例化LocationClient时,需要捕获异常信息
try {
client = new LocationClient(context);
} catch (Exception e) {
e.printStackTrace();
}
client.registerLocationListener(myListener);
LocationClientOption option = new LocationClientOption();
// 设置是否打开gnss进行定位
option.setOpenGnss(true);
// 设置坐标类型
option.setCoorType("bd09ll");
option.setScanSpan(1000);
client.setLocOption(option);
// 启动定位
client.start();
停止定位
// 停止定位
client.stop();
总结
百度地图SDK将定位和基础地图功能拆分,若要实现定位的显示,应确保开发包中包含基本定位功能,并通过定位服务获取定位,并将其传给MapView。