地图APP开发日志 Day 1
一个基于高德SDK个人地图项目
为什么要自己写?
- 不想要广告
- 我只需要某些功能
- 需要一个简介的界面
前期准备
- 在高德控制台申请高德地图key,选择Android平台
- 创建最小sdk为31的Kotlin安卓项目
这个App可能也只会在我经常用的手机上使用,并不想对其他版本进行适配,所以sdk选择到了和手机一致
- 签名文件,在debug和release模式下均使用该签名文件
- 下载开发SDK,选择导航合包
功能
地图显示
- 权限列表
<!--允许访问网络,必选权限--> <uses-permission android:name="android.permission.INTERNET" /> <!--允许获取粗略位置,若用GPS实现定位小蓝点功能则必选--> <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_BACKGROUND_LOCATION"/> <!--允许获取设备和运营商信息,用于问题排查和网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选--> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!--允许获取网络状态,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!--允许获取wifi网络信息,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选--> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!--允许获取wifi状态改变,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选--> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!--允许写入扩展存储,用于数据缓存,若无此权限则写到私有目录--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" /> <!--允许写设备缓存,用于问题排查--> <uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions" /> <!--允许读设备等信息,用于问题排查--> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 还需要在application节点添加key --> <meta-data android:name="com.amap.api.v2.apikey" android:value="key"/>
- jar包和so库
同时build.gradle
需要同步更新android { ... defaultConfig { ndk { //设置支持的SO库架构(开发者可以根据需要,选择一个或多个平台的so) // 我的手机是这个架构 所以只加了这一个,供选择的还有"armeabi", "armeabi-v7a", "x86","x86_64" abiFilters "arm64-v8a" } } ... } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) ... }
- xml页面
根据自己的需要配置MapView
的大小以及布局,我这里是全屏显示地图,同时需要在该View
上层添加控制视图,仿照高德官方的界面添加了搜索栏和定位按钮<com.amap.api.maps.MapView android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true"/>
- 主题样式
因为要全屏显示地图,首先需要将ActionBar
隐藏,直接通过继承带有NoActionBar
的主题,用下方style
可以实现全屏显示视图,同时带来的问题需要通过xml修改,如View
的约束应该考虑到可能被通知栏遮挡、底部导航方式改变时需要动态修改布局(我不想适配所以以我最舒服的导航方式进行开发,直接xml写死底部margin)<style name="MainActivity" parent="Theme.Topcoolchamap"> <item name="android:windowLightStatusBar">true</item> <item name="android:windowTranslucentNavigation">true</item> <item name="android:statusBarColor" >@color/transparent</item> </style>
- 地图初始化
按照文档说明在指定方法执行AMap
对应方法// 设置定位蓝点样式 val myLocationStyle = MyLocationStyle().apply { myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER) showMyLocation(true) strokeColor(getColor(R.color.colorPrimaryVariantAlpha)) radiusFillColor(getColor(R.color.colorPrimaryAlpha)) } amap = binding.map.map.also { it.myLocationStyle = myLocationStyle // 允许显示定位蓝点 it.isMyLocationEnabled = true // 隐藏加减缩放和logo,设置一些列监听 it.uiSettings.let { ui -> // 隐藏地图缩放按钮 ui.isZoomControlsEnabled = false // 隐藏高德地图图标 ui.setLogoBottomMargin(-1000) // 当地图加载完毕时将相机移至中心 it.addOnMapLoadedListener(this) // 定位点发生变化时触发,不断更新当前定位点缓存 it.addOnMyLocationChangeListener(this) } }
完成上述内容即可运行app,就可以看到带有定位蓝点的地图,因为涉及当前地址,所以将地图缩小了
注意
定位失败
需要在Application
中执行下两行内容
AMapLocationClient.updatePrivacyShow(this, true, true)
AMapLocationClient.updatePrivacyAgree(this, true)
无法显示定位蓝点
在高版本中需要提供精确定位权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
手动定位
使用OnMyLocationChangeListener
回调当前定位点时需要判断定位点是否存在,或者经纬度信息不为0
如果使用(0, 0)进行定位的话,可能就飘到大海上了
override fun onMyLocationChange(p0: Location?) {
p0?.let {
if (p0.latitude == 0.0) {
return
}
"定位点发生改变 ${p0.latitude}, ${p0.longitude}".d()
this.location = p0
}
}