您的位置:首页 > 教育 > 培训 > 杭州文化传媒类高端网站建设公司_专业内涵建设8个方面_关键词优化软件_怎样做网站的优化、排名

杭州文化传媒类高端网站建设公司_专业内涵建设8个方面_关键词优化软件_怎样做网站的优化、排名

2025/6/10 8:44:22 来源:https://blog.csdn.net/m0_50774720/article/details/147121933  浏览:    关键词:杭州文化传媒类高端网站建设公司_专业内涵建设8个方面_关键词优化软件_怎样做网站的优化、排名
杭州文化传媒类高端网站建设公司_专业内涵建设8个方面_关键词优化软件_怎样做网站的优化、排名

前言:高德的定位sdk可以获取设备当前的详细信息,如经纬度,具体地址(省->街道)等,

本文主要使用的是定位sdk和地图sdk中的poi搜索功能(以当前位置半径多少米内的关键词搜索)

目录

一、准备工作

1.注册高德的开发者账号

2.在控制台中创建应用,选择Android平台

3.给新建的应用添加一个key,拿到key值

二、项目

1.添加高德 Key

2.代码混淆

3.导入具体的sdk

4.地图管理类

6.在activity/fragment中使用

 7.PoiItem类的属性解释


一、准备工作

1.注册高德的开发者账号

高德控制台

2.在控制台中创建应用,选择Android平台

3.给新建的应用添加一个key,拿到key值

二、项目

1.添加高德 Key

项目的 “AndroidManifest.xml” 文件中,添加如下代码:

     <!--用于进行网络定位--><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/><!--用于访问GPS定位--><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/><!--用于获取运营商信息,用于支持提供运营商信息相关的接口--><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><!--用于访问wifi网络信息,wifi信息会用于进行网络定位--><uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/><!--用于获取wifi的获取权限,wifi信息会用来进行网络定位--><uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/><!--用于访问网络,网络定位需要上网--><uses-permission android:name="android.permission.INTERNET"/><!--用于申请调用A-GPS模块--><uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/><!--用于获取到poi列表后点击item后可以跳转到第三方地图软件中--><queries><package android:name="com.autonavi.minimap" />  <!-- 高德 --><package android:name="com.baidu.BaiduMap" />     <!-- 百度 --></queries><application...... ><meta-dataandroid:name="com.amap.api.v2.apikey"android:value="请输入您的用户Key"/><service android:name="com.amap.api.location.APSService"/>……
</application>

2.代码混淆

在app模块中的proguard-rules.pro文件中添加一下代码

#定位
-keep class com.amap.api.location.**{*;}
-keep class com.amap.api.fence.**{*;}
-keep class com.autonavi.aps.amapapi.model.**{*;}
#搜索
-keep   class com.amap.api.services.**{*;}

3.导入具体的sdk

在app模块下的build.gradle的dependencies代码块中添加以下语句,注意我这里用的很老的版本,新版两个同时导入会有冲突,并且还有些额外的操作,如隐私合规检测等,自己根据官网学吧

    //高德sdk//定位功能implementation 'com.amap.api:location:3.3.0'//搜索功能implementation 'com.amap.api:search:5.0.0'

4.地图管理类

由于我的需求只需要获取加油站和充电站,所以用了枚举,其实你可以在getPoiData()方法中的类型位置输入任何关键词的

//地图定位
object MapManger {// 定义权限请求码internal val REQUEST_CODE_LOCATION = 100//定位客户端对象var mLocationClient: AMapLocationClient? = null// 定位结果回调var locationCallback: LocationCallback? = null//当前位置的定位信息var locationInfo: LocationInfo? = null//附近的加油站列表var gasStationPoiList: ArrayList<PoiItem>? = null//附近的充电站列表var chargeStationPoiList: ArrayList<PoiItem>? = null//上次的定位成功时间var lastLocationSuccessTime = 0L//如果定位失败后,重新定位间隔时间var relocationTime = 5000Lfun init() {// 初始化定位mLocationClient = AMapLocationClient(App.app)mLocationClient!!.setLocationOption(getDefaultOption())// 设置定位回调监听mLocationClient!!.setLocationListener(object : AMapLocationListener {override fun onLocationChanged(amapLocation: AMapLocation?) {if (amapLocation != null) {if (amapLocation.errorCode == 0) {stopLocation()locationInfo = LocationInfo(amapLocation.latitude,amapLocation.longitude,amapLocation.accuracy,amapLocation.address,amapLocation.country,amapLocation.province,amapLocation.city,amapLocation.district,amapLocation.street,amapLocation.streetNum,amapLocation.cityCode,amapLocation.adCode,amapLocation.aoiName)locationCallback?.success()lastLocationSuccessTime = System.currentTimeMillis()} else {locationCallback?.failure()//定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。Log.e("AmapError","location Error, ErrCode:${amapLocation.getErrorCode()},errInfo:${amapLocation.getErrorInfo()}")}}}})}//开始定位fun startLocation() {try {if (mLocationClient == null) {init()}if (locationInfo == null || System.currentTimeMillis() - lastLocationSuccessTime >= 1000 * 60 * 10) {mLocationClient!!.startLocation();}} catch (e: Exception) {e.printStackTrace()}}//停止定位fun stopLocation() {try {mLocationClient?.stopLocation()} catch (e: Exception) {e.printStackTrace()}}//销毁@JvmStatic //在Java中声明为静态方法fun destroyLocation() {if (null != mLocationClient) {/*** 如果AMapLocationClient是在当前Activity实例化的,* 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy*/stopLocation()mLocationClient?.onDestroy()mLocationClient = nullmLocationClient = null}}//获取poi数据fun getPoiData(context: Context,poiType: PoiType,poiSearchListener: PoiSearch.OnPoiSearchListener) {val query = PoiSearch.Query(poiType.name, "", locationInfo?.cityCode);query.setPageSize(50);// 设置每页最多返回多少条poiitemquery.setPageNum(0);//设置查询页码val poiSearch = PoiSearch(context, query);poiSearch.setOnPoiSearchListener(poiSearchListener)// 设置周边搜索的中心点(经纬度)以及半径(米)poiSearch.setBound(SearchBound(LatLonPoint(locationInfo?.latitude ?: 0.0,locationInfo?.longitude ?: 0.0), 15000));//设置周边搜索的中心点以及半径poiSearch.searchPOIAsyn()}/*** 打开系统地图选择弹窗,跳转到第三方地图的POI详情页* @param context 上下文* @param poi 包含以下字段的数据类:*            id: String (高德POI ID),*            name: String,*            latitude: Double,*            longitude: Double,*            city: String? (百度地图必需)*/fun openPoiDetail(context: Context, poi: PoiItem) {val encodedName = URLEncoder.encode(poi.title, "UTF-8")val encodedAddress = URLEncoder.encode(poi.snippet ?: poi.title, "UTF-8")val mapUris = listOf(// 高德地图(使用坐标+名称方案)Uri.parse("amapuri://viewMap?" +"sourceApplication=${context.packageName}" +"&poiname=$encodedName" +"&lat=${poi.latLonPoint.latitude}" +"&lon=${poi.latLonPoint.longitude}" +"&dev=0") to "com.autonavi.minimap",// 百度地图(使用marker方案)Uri.parse("baidumap://map/marker?" +"location=${poi.latLonPoint.latitude},${poi.latLonPoint.longitude}" +"&title=$encodedName" +"&content=$encodedAddress" +"&coord_type=gcj02" +"&src=${context.packageName}") to "com.baidu.BaiduMap",// 网页版高德Uri.parse("https://uri.amap.com/marker?" +"position=${poi.latLonPoint.longitude},${poi.latLonPoint.latitude}" +"&name=$encodedName" +"&src=${context.packageName}") to null,// 网页版百度Uri.parse("https://map.baidu.com/marker?" +"location=${poi.latLonPoint.latitude},${poi.latLonPoint.longitude}" +"&title=$encodedName" +"&content=$encodedAddress" +"&autoOpen=true") to null)// 过滤可用应用val availableIntents = mapUris.mapNotNull { (uri, packageName) ->packageName?.let {Intent(Intent.ACTION_VIEW, uri).apply {`package` = packageNameaddFlags(Intent.FLAG_ACTIVITY_NEW_TASK)}.takeIf {context.packageManager.resolveActivity(it, 0) != null}} ?: Intent(Intent.ACTION_VIEW, uri)}// 启动系统选择器if (availableIntents.isNotEmpty()) {context.startActivity(Intent.createChooser(availableIntents.first(),"在地图中查看").apply {putExtra(Intent.EXTRA_INITIAL_INTENTS, availableIntents.drop(1).toTypedArray())})} else {Toast.makeText(context, "未找到可用地图应用", Toast.LENGTH_SHORT).show()}}//获取定位参数配置private fun getDefaultOption(): AMapLocationClientOption {val mOption = AMapLocationClientOption()// 可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式mOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy// 可选,设置是否gps优先,只在高精度模式下有效。默认关闭// mOption.isGpsFirst = false// 可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效mOption.httpTimeOut = 10000// 可选,设置定位间隔。默认为2秒// mOption.interval = 2000// 可选,设置是否单次定位。默认是falsemOption.isOnceLocation = true// 可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用// mOption.isOnceLocationLatest = true// 可选,设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP// AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP)// 可选// mOption.isSensorEnable = false// 可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差// mOption.isWifiScan = true// 可选,设置是否使用缓存定位,默认为truemOption.isLocationCacheEnable = false// 可选,设置逆地理信息的语言,默认值为默认语言(根据所在地区选择语言)// mOption.geoLanguage = AMapLocationClientOption.GeoLanguage.DEFAULTreturn mOption}//检查所需权限fun checkPermissions(): Boolean {val permissions = getRequiredPermissions()return if (permissions.isNotEmpty()) false else true}fun getRequiredPermissions(): Array<String> {val permissions = mutableListOf<String>()if (!checkPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {permissions.add(Manifest.permission.ACCESS_FINE_LOCATION)}if (!checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION)) {permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION)}return permissions.toTypedArray()}// 检查单个权限fun checkPermission(permission: String): Boolean {return ContextCompat.checkSelfPermission(App.app as Context,permission) == PackageManager.PERMISSION_GRANTED}data class LocationInfo(val latitude: Double,        // 纬度val longitude: Double,       // 经度val accuracy: Float,         // 精度val address: String?,        // 地址(可能为null)val country: String?,        // 国家val province: String?,       // 省份val city: String?,           // 城市val district: String?,       // 区县val street: String?,         // 街道val streetNum: String?,      // 门牌号val cityCode: String?,       // 城市编码val adCode: String?,         // 区域编码val aoiName: String?         // AOI信息)interface LocationCallback {fun success()fun failure()}enum class PoiType {加油站,充电站}}

6.在activity/fragment中使用

下面是在fragment中使用,只需要把requireActivity(),requireContext()等获取上下文的方法替换为this就行


var mapManger = MapMangeroverride fun onResume() {super.onResume()if (mapManger.checkPermissions()) {mapManger.startLocation()} else {//弹出权限申请弹窗,点击确定按钮去动态申请权限,这里直接申请ActivityCompat.requestPermissions(requireActivity(),mapManger.getRequiredPermissions(),mapManger.REQUEST_CODE_LOCATION)}
}//activity的话在onCreate()中override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)mapManger.locationCallback = object : LocationCallback {override fun success() {//定位成功,获取数据getPoiData()}override fun failure() {//重新定位Handler().postDelayed({mapManger.relocationTime = mapManger.relocationTime*1.5.toLong()mapManger.startLocation()}, mapManger.relocationTime)}}//如果你有两个界面功能相似,像一个界面是加油站一个是充电站的话,由于mapManger是单例类,全局用一个对象,如果别的界面进行了定位,这个界面将不会收到回调,重新拉一次自己需要的数据if (mapManger.locationInfo!= null && mapManger.gasStationPoiList == null){//说明在别的界面进行了定位,当前界面不会触发定位成功回调,手动一次获取数据getPoiData()}}fun getPoiData(){binding.cityNameTv.text = mapManger.locationInfo?.citymapManger.getPoiData(requireContext(),MapManger.PoiType.加油站,object : OnPoiSearchListener {override fun onPoiSearched(poiResult: PoiResult?, p1: Int) {val list = poiResult?.getPois()if (!list.isNullOrEmpty()) {binding.noDataFl.visibility = View.GONEmapManger.gasStationPoiList = list//这里已经获取到列表,可以将数据填充到recyclerview中//如果要点击某项item进行跳转的话,调用mapManger.openPoiDetail()方法就行}}override fun onPoiItemSearched(p0: PoiItem?, p1: Int) {}})}

此外还应该在activity的onDestroy中调用回收方法,以回收资源,防止内存泄漏

MapManger.destroyLocation()  

 7.PoiItem类的属性解释

poiId //poi的ID
title //poi名称
adName //所在区的名称 
snippet //区以下的详细地址 街道等
distance //距离(单位米)
photos //图片列表
tel  //电话号
latLonPoint //经纬度  获取单个经度/纬度 :latLonPoint.latitude latLonPoint.longitude//其余还有一些 像 省份、城市、邮编等信息不再列举了,和管理类里的LocationInfo对象属性应该差不多

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com