高德SDK提供了定位、地圖、導(dǎo)航相關(guān)的豐富的接口。本文記載我接入高德SDK過程及遇到的問題,如有任何錯誤煩請指正。
1 接入準備
1.1 申請key
首先,要申請高德key。參考https://lbs.amap.com/faq/android/map-sdk/create-project/43112首先獲得SHA1碼,如果存在keytool命令失效的情況,可以跳轉(zhuǎn)到keytool.exe所在目錄再進行操作。
https://console.amap.com/dev/key/app填寫相關(guān)信息,提交,得到高德的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'
}
}
然后,加入高德地圖相關(guān)依賴:
//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地圖的依賴,否則會產(chǎn)生報錯:More than one file was found with OS independent path
由于定位需要用到包括網(wǎng)絡(luò)、定位以及離線地圖緩存需要的存儲權(quán)限,推薦使用livePermission獲取動態(tài)權(quán)限:
//LivePermission
implementation 'com.ftd.livepermissions:livepermissions:1.0.2'
接下來,配置AndroidManifest.xml:
申明權(quán)限:
<!-- 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標簽范圍內(nèi)加入高德key以及高德定位服務(wù):
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="(高德key的值)" />
<service android:name="com.amap.api.location.APSService" />
2 簡單顯示地圖及所在定位點
創(chuàng)建一個MapActivity及對應(yīng)的xml文件,activity_map當中加入一個高德地圖的容器:
<com.amap.api.maps.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
在MapActivity當中動態(tài)申請存儲權(quán)限:
//如果設(shè)置了target > 28,需要增加這個權(quán)限,否則不會彈出"始終允許"這個選擇框
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當中分別調(diào)用mapView的相關(guān)方法。
aMap初始化:
private lateinit var aMap: AMap
//onCreate里面進行
aMap = mapView?.getMap()!!
至此,已經(jīng)可以看到地圖顯示。接下來,進行定位藍點的初始化:
private lateinit var mLocationStyle: MyLocationStyle
//onCreate里面進行
mLocationStyle = MyLocationStyle().apply {
myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)
//不設(shè)置默認是MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE
interval(2000)
showMyLocation(true)
}
aMap.apply {
myLocationStyle = mLocationStyle //設(shè)置定位藍點的Style
uiSettings.isMyLocationButtonEnabled = true //設(shè)置默認定位按鈕是否顯示,非必需設(shè)置
isMyLocationEnabled = true // 設(shè)置為true表示啟動顯示定位藍點,false表示隱藏定位藍點并不進行定位,默認是false
}
定位模式有以下八種:
myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);//只定位一次。
myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) ;//定位一次,且將視角移動到地圖中心點。
myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW) ;//連續(xù)定位、且將視角移動到地圖中心點,定位藍點跟隨設(shè)備移動。(1秒1次定位)
myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);//連續(xù)定位、且將視角移動到地圖中心點,地圖依照設(shè)備方向旋轉(zhuǎn),定位點會跟隨設(shè)備移動。(1秒1次定位)
myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//連續(xù)定位、且將視角移動到地圖中心點,定位點依照設(shè)備方向旋轉(zhuǎn),并且會跟隨設(shè)備移動。(1秒1次定位)默認執(zhí)行此種模式。
myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//連續(xù)定位、藍點不會移動到地圖中心點,定位點依照設(shè)備方向旋轉(zhuǎn),并且藍點會跟隨設(shè)備移動。
myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);//連續(xù)定位、藍點不會移動到地圖中心點,并且藍點會跟隨設(shè)備移動。
myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE_NO_CENTER);//連續(xù)定位、藍點不會移動到地圖中心點,地圖依照設(shè)備方向旋轉(zhuǎn),并且藍點會跟隨設(shè)備移動。
點擊右上角的定位按鈕,視圖的中心移至定位點,并且可以看到定位的藍色箭頭會隨著手機方向移動,并且每兩秒鐘更新位置。移動地圖時,視圖中心不會因為定位點變化而移動。
在高德地圖-顯示定位藍點,可以看到更多個性化設(shè)置的內(nèi)容,包括可以自定義定位藍點的圖標、定位精度圈等。
3 地圖中心移至定位點
private fun setLocation() {
//初始化AMapLocationClientOption對象
val mLocationOption = AMapLocationClientOption().apply {
locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy //設(shè)置定位模式為高精度模式
// isOnceLocation = true
/**獲取最近3s內(nèi)精度最高的一次定位結(jié)果:
* 設(shè)置isOnceLocationLatest為true,啟動定位時SDK會返回最近3s內(nèi)精度最高的一次定位結(jié)果
* 如果設(shè)置其為true,isOnceLocation也會被設(shè)置為true,反之不會,默認為false
*/
isOnceLocationLatest = true
}
//初始化定位
mLocationClient = AMapLocationClient(applicationContext)
mLocationClient.setLocationListener { aMapLocation ->
if (aMapLocation != null) {
if (aMapLocation.errorCode == 0) {
//定位成功回調(diào)信息,設(shè)置相關(guān)消息
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)
//設(shè)置定位回調(diào)監(jiān)聽
mLocationClient.setLocationOption(mLocationOption)
}
//設(shè)置場景模式后最好調(diào)用一次stop,再調(diào)用start以保證場景模式生效
mLocationClient.stopLocation()
mLocationClient.startLocation()
}