地图SDK Android版开发 3 显示定位
前言
本文主要介绍腾讯地图显示定位相关的功能和接口,以及使用方法。
- 腾讯地图SDK不负责获取位置,由外界提供。
- 开启地图定位功能,建议使用腾讯Android定位SDK设置定位。
因此,要在地图中显示定位,主要有两个步骤:
- 获取定位数据。
- 将定位数据在地图中显示。
本文主要包括以下内容:
- 介绍几个概念,如定位数据,定位模式和定位样式。
- 简单介绍在地图中显示定位相关类和接口和示例代码。
- 简单介绍下获取定位数据相关类和接口和示例代码。
概念
定位数据
- 定位包中的
TencentLocation
地理位置接口类。 - 地理位置由经度,纬度,高度,精度组成,可能还包含名字、地址等其他可选信息。
- 部分接口如下:
类型 | 方法 | 说明 |
---|---|---|
double | getLatitude() | 返回当前位置的纬度 |
double | getLongitude() | 返回当前位置的经度 |
float | getAccuracy() | 返回当前位置的精度 |
float | getBearing() | 返回当前位置方向, 单位为度, 仅当位置来自GPS时可能有效 |
double | getDirection() | 返回方向,仅来自传感器方向,如果是gps,则直接获取gps方向 |
long | getTime() | 返回当前位置的生成时间 |
float | getSpeed() | 返回移动速度, 单位为m/s (米/秒), 仅当位置来自GPS时可能有效 |
String | getName() | 返回当前位置的名称 |
String | getNation() | 返回当前位置的国家 |
String | getProvince() | 返回当前位置的省份 |
String | getCity() | 返回当前位置的城市 |
定位模式
- 在地图的各种应用场景中,用户对定位点展示时也希望地图能跟随定位点旋转、移动等多种行为。
- 在腾讯地图 SDK 中可以设置定位点展示时地图的行为模式:
定位模式 | 说明 | |
---|---|---|
1 | LOCATION_TYPE_FOLLOW_NO_CENTER | 连续定位,但不会移动到地图中心点,并且会跟随设备移动 |
2 | LOCATION_TYPE_LOCATION_ROTATE | 连续定位,且将视角移动到地图中心,定位点依照设备方向旋转,并且会跟随设备移动,默认是此种类型 |
3 | LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER | 连续定位,但不会移动到地图中心点,定位点依照设备方向旋转,并且跟随设备移动 |
4 | LOCATION_TYPE_MAP_ROTATE_NO_CENTER | 连续定位,但不会移动到地图中心点,地图依照设备方向旋转,并且会跟随设备移动 |
定位样式类
MyLocationStyle
类可设定定位模式,以及定制化样式。
类型 | 方法 | 说明 |
---|---|---|
MyLocationStyle | myLocationType(int myLocationType) | 设置定位蓝点模式。 |
MyLocationStyle | icon(BitmapDescriptor myLocationIcon) | 设置定位(当前位置)的icon图标。 |
MyLocationStyle | anchor(float u, float v) | 设置定位图标的锚点。 |
MyLocationStyle | fillColor(int fillColor) | 设置圆形区域(以定位位置为圆心,定位半径的圆形区域)的填充颜色。 |
MyLocationStyle | strokeColor(int strokeColor) | 设置圆形区域(以定位位置为圆心,定位半径的圆形区域)的边框颜色。 |
MyLocationStyle | strokeWidth(int strokeWidth) | 设置圆形区域(以定位位置为圆心,定位半径的圆形区域)的边框宽度。 |
MyLocationStyle | setLocationCompass(LocationCompass locationCompass) | 设置定位标罗盘。 |
MyLocationStyle | setLocationNavigationGravityline(LocationNavigationGravityline locationNavigationGravityline) | 设置定位标导航引导线。 |
显示定位
地图包相关类和接口
TencentMap
TencentMap
地图类与定位相关的接口,包括设置定位数据源,设置是否打开定位图层、设置定位模式和定位风格。
类型 | 方法 | 说明 |
---|---|---|
void | setLocationSource(LocationSource locationSource) | 设置我的位置信息来源 |
void | setMyLocationEnabled(boolean enable) | 设置是否显示我的位置 |
void | setMyLocationStyle(MyLocationStyle myLocationStyle) | 设置定位的样式 |
LocationSource
LocationSource
设置我的位置信息接口类,为地图提供定位数据。包含activate
和deactivate
回调方法。- 在
activate
激活定位源中,设置定位初始化及启动定位。 - 在
deactivate
停止定位中,停止定位的相关调用。
- 在
类型 | 方法 | 说明 |
---|---|---|
void | activate(LocationSource.OnLocationChangedListener onlocationchangedlistener) | 设置位置变化回调接口 |
void | deactivate() | 取消位置变化回调 |
LocationSource.OnLocationChangedListener
- 当我的位置有变化时,调用的接口。
类型 | 方法 | 说明 |
---|---|---|
void | onLocationChanged(android.location.Location location) | 新的位置信息设置函数,由调用者把新的位置信息传给地图SDK |
示例代码
- 地图加载完成时,显示我的位置,定位模式和样式,定位源。
// 设置默认定位按钮是否显示
map.getUiSettings().setMyLocationButtonEnabled(true);
// 设置显示我的位置
map.setMyLocationEnabled(true);
// 设置定位的样式
// 定位模式:连续定位,且将视角移动到地图中心,定位点依照设备方向旋转,并且会跟随设备移动,默认是此种类型
MyLocationStyle locationStyle = new MyLocationStyle();
locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
map.setMyLocationStyle(locationStyle);
// 设置我的位置信息来源
map.setLocationSource(new MyLocationSource());
- 自定义``MyLocationSource
,实现
LocationSource`接口。
class MyLocationSource implements LocationSource {
/**
* 设置位置变化回调接口
* @param onLocationChangedListener 位置变化回调接口
*/
@Override
public void activate(LocationSource.OnLocationChangedListener onLocationChangedListener) {
// TODO 请求定位
// 获取位置后调用 LocationSource.OnLocationChangedListener.onLocationChanged 即可在地图上将位置显示出来
// onLocationChangedListener.onLocationChanged(location);
}
/**
* 取消位置变化回调
*/
@Override
public void deactivate() {
// TODO 停止定位
}
}
模拟定位显示
MyLocationSource
类activate
中,设置模拟坐标,以验证显示定位的功能。
// 模拟定位位置
double latitude = 39.923615;
double longitude = 116.49094;
// TODO 未找到坐标转换的接口
Location location = new Location("SimulateLocation");
location.setLatitude(latitude);
location.setLongitude(longitude);
// 设置位置
onLocationChangedListener.onLocationChanged(location);
效果图
获取定位
定位包相关类和接口
TencentLocationManager
- 用于访问腾讯定位服务的类, 腾讯定位服务可周期性向客户端提供位置更新
TencentLocationManager
部分接口如下:
类型 | 方法 | 说明 |
---|---|---|
static void | setUserAgreePrivacy(boolean isAgree) | 设置用户是否同意隐私协议政策 |
static TencentLocationManager | getInstance(Context context) | 获取腾讯定位服务实例,该方法需要在带有looper的线程调用,SDK会保证无耗时操作并立即返回 |
void | setCoordinateType(int coordinateType) | 设置坐标系 |
int | requestLocationUpdates(TencentLocationRequest request, TencentLocationListener listener) | 请求定位, 位置更新将通过 listener 回调通知 |
void | removeUpdates(TencentLocationListener listener) | 移除位置监听器并停止定位 |
TencentLocationRequest
- 定位请求, 客户端使用本类指定定位周期等参数
类型 | 方法 | 说明 |
---|---|---|
static TencentLocationRequest | create() | 创建一个缺省的定位请求 |
TencentLocationRequest | setInterval(long millis) | 设置定位周期(位置监听器回调周期), 单位为 ms (毫秒) |
TencentLocationListener
- 位置监听器
- 定位 SDK 通过位置监听器将位置变化通知给客户端
类型 | 方法 | 说明 |
---|---|---|
void | onLocationChanged(TencentLocation location, int error, String reason) | 位置发生变化 |
void | onStatusUpdate(String name, int status, String desc) | GPS, WiFi, Radio 等状态发生变化 |
定位权限
官方推荐:
- 随着Android版本的升级,权限使用方面也有变动,具体可参考实用文档中针对Android各个版本的适配文档。
- 定位服务是一个重度依赖用户授权的功能,因此在App设计时必须充分考虑获取用户权限的方式,合理引导用户授予权限。
<!-- 通过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.INTERNET"/>
<!-- 访问WiFi状态,需要WiFi信息用于网络定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- 修改WiFi状态,发起WiFi扫描, 需要WiFi信息用于网络定位 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- 访问网络状态, 检测网络的可用性,需要网络运营商相关信息用于网络定位 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 访问网络的变化, 需要某些信息用于网络定位 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!-- 蓝牙扫描权限 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!-- 前台service权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- 后台定位权限 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<!-- A-GPS辅助定位权限,方便GPS快速准确定位 -->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
隐私合规接口
- Android定位SDK自v7.4.6版本起增加了隐私合规接口,与之前版本不兼容,
- 开发者使用v7.4.6及之后的版本需要保证用户同意隐私政策后调用setUserAgreePrivacy接口,设置同意定位SDK的隐私政策后才能正常使用定位SDK功能。
- 新增定位SDK隐私政策确认接口setUserAgreePrivacy(boolean isAgree),接口说明如下:
/**
* 设置用户是否同意隐私协议政策
* 调用其他接口前必须首先调用此接口进行用户是否同意隐私政策的设置,传入true后才能正常使用定位功能
* @param isAgree 是否同意隐私政策
*/
public static void setUserAgreePrivacy(boolean isAgree) {
isAgreePrivacy = isAgree;
}
- 在构造TencentLocationManager以及使用定位功能前,需要先设置同意定位SDK的隐私政策,否则所有定位SDK相关功能不可用,调用定位功能会返回错误码,具体见接口文档
TencentLocationManager.setUserAgreePrivacy(true);
部分示例代码
private TencentLocationManager locationManager;
private TencentLocationRequest locationRequest;
private LocationSource.OnLocationChangedListener locationChangedListener;
class MyLocationSource implements LocationSource, TencentLocationListener {
/**
* 设置位置变化回调接口
* @param onLocationChangedListener 位置变化回调接口
*/
@Override
public void activate(LocationSource.OnLocationChangedListener onLocationChangedListener) {
locationChangedListener = onLocationChangedListener;
// 用于访问腾讯定位服务的类, 周期性向客户端提供位置更新
locationManager = TencentLocationManager.getInstance(context);
// 设置坐标系
locationManager.setCoordinateType(TencentLocationManager.COORDINATE_TYPE_GCJ02);
// 创建定位请求
locationRequest = TencentLocationRequest.create();
// 设置定位周期(位置监听器回调周期)为3s
locationRequest.setInterval(3000);
// 请求定位, 位置更新将通过 listener 回调通知
locationManager.requestLocationUpdates(locationRequest, this, Looper.myLooper());
}
/**
* 取消位置变化回调
*/
@Override
public void deactivate() {
locationManager.removeUpdates(this);
locationRequest = null;
locationChangedListener = null;
}
/**
* 位置发生变化.
* @param tencentLocation 新的位置, 可能来自缓存. 定位失败时 location 无效或者为 null
* @param error 错误码, 仅当错误码为 TencentLocation.ERROR_OK 时表示定位成功, 为其他值时表示定位失败
* @param reason 错误描述, 简要描述错误原因
*/
@Override
public void onLocationChanged(TencentLocation tencentLocation, int error, String reason) {
if (error == TencentLocation.ERROR_OK && locationChangedListener != null) {
Location location = new Location(tencentLocation.getProvider());
// 设置经纬度
location.setLatitude(tencentLocation.getLatitude());
location.setLongitude(tencentLocation.getLongitude());
// 设置精度,这个值会被设置为定位点上表示精度的圆形半径
location.setAccuracy(tencentLocation.getAccuracy());
// 设置定位标的旋转角度,
// 注意 tencentLocation.getBearing() 只有在 gps 时才有可能获取
// location.setBearing((float) tencentLocation.getBearing());
// 设置定位标的旋转角度,注意 tencentLocation.getDirection() 返回的方向,仅来自传感器方向,
// 如果是gps,则直接获取gps方向
location.setBearing((float) tencentLocation.getDirection());
// 设置位置
locationChangedListener.onLocationChanged(location);
}
}
/**
* GPS, WiFi, Radio 等状态发生变化
* @param name 设备名, GPS, WIFI, CELL 中的某个
* @param status 状态码,
* STATUS_ENABLED, STATUS_DISABLED, STATUS_UNKNOWN, STATUS_GPS_AVAILABLE,
* STATUS_GPS_UNAVAILABLE, STATUS_DENIED中的某个
* 在使用status之前,请先按照name进行区分
* @param desc 状态描述
*/
@Override
public void onStatusUpdate(String name, int status, String desc) {
//GPS, WiFi, Radio 等状态发生变化
Log.v("State changed", name + "===" + status + "===" + desc);
}
}
总结
腾讯地图SDK将定位和基础地图功能拆分,若要实现定位的显示,应确保开发包中包含基本定位功能,并通过定位服务获取定位。
腾讯地图SDK集成腾讯地图 SDK 主要有两种方式:
- 手动将腾讯地图 sdk 的 jar 包和 so 库或者aar包导入到工程
- 通过 Gradle 配置 maven 或 jcenter 仓库集成 SDK
最后补充仓库集成配置:
implementation 'com.tencent.map:tencent-map-vector-sdk:5.6.0'
implementation 'com.tencent.map:sdk-utilities:1.0.9'
implementation 'com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.5.4.3'
标签:定位,void,位置,接口,设置,腾讯,Android,SDK
From: https://blog.csdn.net/kikikiki001/article/details/141176440