高德SDK提供了定位、地图、导航相关的丰富的接口。本文记载我接入高德SDK过程及遇到的问题,如有任何错误烦请指正。
1 接入准备
1.1 申请key
首先,要申请高德key。参考https://lbs.amap.com/faq/android/map-sdk/create-project/43112首先获得SHA1码,如果存在keytool命令失效的情况,可以跳转到keytool.exe所在目录再进行操作。
https://console.amap.com/dev/key/app填写相关信息,提交,得到高德的key。
1.2 项目配置
首先,配置项目的build.gradle,打包时加入签名文件:
signingConfigs{
release{
storeFile file //签名文件路径
storePassword "××××××"
keyAlias "××××××"
keyPassword "××××××"
}
}
buildTypes {
debug{
signingConfig signingConfigs.release
}
release {
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
然后,加入高德地图相关依赖:
//Amap
implementation "com.amap.api:3dmap:$amap_version"
implementation 'com.amap.api:location:5.3.0'
implementation 'com.amap.api:search:7.7.0'
注意:高德地图不建议同时使用3D和2D地图,如无必要,不要加入2d地图的依赖,否则会产生报错:More than one file was found with OS independent path
由于定位需要用到包括网络、定位以及离线地图缓存需要的存储权限,推荐使用livePermission获取动态权限:
//LivePermission
implementation 'com.ftd.livepermissions:livepermissions:1.0.2'
接下来,配置AndroidManifest.xml:
申明权限:
<!-- storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- network -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- phone state -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- location -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
在application标签范围内加入高德key以及高德定位服务:
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="(高德key的值)" />
<service android:name="com.amap.api.location.APSService" />
2 简单显示地图及所在定位点
创建一个MapActivity及对应的xml文件,activity_map当中加入一个高德地图的容器:
<com.amap.api.maps.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
在MapActivity当中动态申请存储权限:
//如果设置了target > 28,需要增加这个权限,否则不会弹出"始终允许"这个选择框
private val BACK_LOCATION_PERMISSION = "android.permission.ACCESS_BACKGROUND_LOCATION"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
LivePermissions(this).request(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
BACK_LOCATION_PERMISSION
)
setContentView(R.layout.activity_map)
mapView初始化:
private var mapView: MapView? = null
//onCreate里面进行
mapView = findViewById(R.id.map)
mapView?.onCreate(savedInstanceState)
再在onDestroy、onResume、onPause、onSaveInstanceState当中分别调用mapView的相关方法。
aMap初始化:
private lateinit var aMap: AMap
//onCreate里面进行
aMap = mapView?.getMap()!!
至此,已经可以看到地图显示。接下来,进行定位蓝点的初始化:
private lateinit var mLocationStyle: MyLocationStyle
//onCreate里面进行
mLocationStyle = MyLocationStyle().apply {
myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)
//不设置默认是MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE
interval(2000)
showMyLocation(true)
}
aMap.apply {
myLocationStyle = mLocationStyle //设置定位蓝点的Style
uiSettings.isMyLocationButtonEnabled = true //设置默认定位按钮是否显示,非必需设置
isMyLocationEnabled = true // 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false
}
定位模式有以下八种:
myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);//只定位一次。
myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) ;//定位一次,且将视角移动到地图中心点。
myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW) ;//连续定位、且将视角移动到地图中心点,定位蓝点跟随设备移动。(1秒1次定位)
myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);//连续定位、且将视角移动到地图中心点,地图依照设备方向旋转,定位点会跟随设备移动。(1秒1次定位)
myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)默认执行此种模式。
myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动。
myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,并且蓝点会跟随设备移动。
myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,地图依照设备方向旋转,并且蓝点会跟随设备移动。
点击右上角的定位按钮,视图的中心移至定位点,并且可以看到定位的蓝色箭头会随着手机方向移动,并且每两秒钟更新位置。移动地图时,视图中心不会因为定位点变化而移动。
在高德地图-显示定位蓝点,可以看到更多个性化设置的内容,包括可以自定义定位蓝点的图标、定位精度圈等。
3 地图中心移至定位点
private fun setLocation() {
//初始化AMapLocationClientOption对象
val mLocationOption = AMapLocationClientOption().apply {
locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy //设置定位模式为高精度模式
// isOnceLocation = true
/**获取最近3s内精度最高的一次定位结果:
* 设置isOnceLocationLatest为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果
* 如果设置其为true,isOnceLocation也会被设置为true,反之不会,默认为false
*/
isOnceLocationLatest = true
}
//初始化定位
mLocationClient = AMapLocationClient(applicationContext)
mLocationClient.setLocationListener { aMapLocation ->
if (aMapLocation != null) {
if (aMapLocation.errorCode == 0) {
//定位成功回调信息,设置相关消息
mListener?.onLocationChanged(aMapLocation)
latitude = aMapLocation.latitude
longitude = aMapLocation.longitude
mLocationClient.stopLocation()
} else {
//显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。
Log.e(
"AMapError", ("location Error, ErrCode:"
+ aMapLocation.errorCode) + ", errInfo:"
+ aMapLocation.errorInfo
)
}
}
Log.i(TAG, "位置:latitude:$latitude latitude:$longitude")
centerPoint = LatLng(latitude, longitude)
val mCameraUpdate =
CameraUpdateFactory.newCameraPosition(CameraPosition(centerPoint, 12F, 0F, 0F))
aMap.moveCamera(mCameraUpdate)
//设置定位回调监听
mLocationClient.setLocationOption(mLocationOption)
}
//设置场景模式后最好调用一次stop,再调用start以保证场景模式生效
mLocationClient.stopLocation()
mLocationClient.startLocation()
}