Google Maps setOnPoiClickListener返回点击位置而非POI坐标问题排查
问题原因与解决方案
问题本质
你遇到的是Google Maps Android SDK 18.2.0 版本的预期行为:OnPoiClick 回调返回的 PointOfInterest.latLng 字段,实际是用户点击屏幕位置对应的地理坐标,而非POI官方注册的中心点坐标。官方文档中描述的“POI经纬度”,指的是通过Place ID查询到的官方坐标,而非回调直接返回的点击坐标。
无延迟的实现思路
1. 升级SDK版本
后续版本(如 com.google.android.gms:play-services-maps:19.0.0+)优化了 OnPoiClick 回调的返回逻辑,会直接返回POI的官方中心点坐标。你可以尝试升级依赖版本验证:
implementation 'com.google.android.gms:play-services-maps:19.0.0'
2. 本地缓存POI坐标
如果无法升级SDK,可对已获取过的POI做本地缓存,避免重复网络请求的延迟:
- 首次点击某POI时,调用
FetchPlaceRequest获取官方坐标并存储(比如用SharedPreferences或本地数据库) - 后续点击同一POI时,直接从缓存读取坐标
示例代码片段:
// 用SharedPreferences实现简单缓存 val poiCache = context.getSharedPreferences("POICoords", Context.MODE_PRIVATE) setOnPoiClickListener { poi -> val cachedLat = poiCache.getFloat("${poi.placeId}_lat", Float.NaN) val cachedLng = poiCache.getFloat("${poi.placeId}_lng", Float.NaN) if (!cachedLat.isNaN() && !cachedLng.isNaN()) { // 使用缓存的官方坐标 Log.d("POIClick", "Cached POI ${poi.name}, lat: $cachedLat, lng: $cachedLng") } else { // 首次获取,请求并缓存官方坐标 val placeFields = listOf(Place.Field.LAT_LNG) val request = FetchPlaceRequest.newInstance(poi.placeId, placeFields) placesClient.fetchPlace(request).addOnSuccessListener { response -> val officialLatLng = response.place.latLng poiCache.edit() .putFloat("${poi.placeId}_lat", officialLatLng.latitude.toFloat()) .putFloat("${poi.placeId}_lng", officialLatLng.longitude.toFloat()) .apply() Log.d("POIClick", "Official POI ${poi.name}, lat: ${officialLatLng.latitude}, lng: ${officialLatLng.longitude}") } } }
3. 近似估算中心点(低精度场景)
如果对坐标精度要求不高,可通过记录同一POI的多次点击坐标,计算平均值作为近似中心点。但这种方法精度有限,仅适用于非精准需求场景。
内容的提问来源于stack exchange,提问作者superpav
相关产品推荐
相关产品推荐

