Android Studio Kotlin中LatLng类型不匹配及未解析引用问题求助
修复LocationService类中的类型不匹配与未解析引用错误
错误原因分析
- 类型不匹配:代码混用了两个不同包的
LatLng类:com.google.android.gms.maps.model.LatLng(Android地图SDK)和com.google.maps.model.LatLng(Google Maps服务Java客户端)。Places API方法需要后者,但代码传递了前者,导致类型冲突。 - 未解析引用bounds:Google Places API的
nearbySearchQuery没有.bounds()方法,正确的方法名是.locationRestriction(),用于传入矩形边界。
修复后的完整代码
import android.Manifest import android.content.Context import android.content.pm.PackageManager import android.location.Location import androidx.core.content.ContextCompat import com.example.eventfinder.utils.LocationUtils import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices import com.google.android.gms.maps.model.LatLng as AndroidLatLng import com.google.maps.GeoApiContext import com.google.maps.PlacesApi import com.google.maps.model.LatLng as GoogleMapsLatLng import com.google.maps.model.LatLngBounds as GoogleMapsLatLngBounds import com.google.maps.model.PlacesSearchResult import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.tasks.await import kotlinx.coroutines.withContext import kotlin.math.min class LocationService(private val context: Context) { private val fusedLocationClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context) private val locationPermission = Manifest.permission.ACCESS_FINE_LOCATION private val apiKey = "Your API Key" // Replace with your API key interface LocationCallback { fun onLocationResult(location: Location?) fun onCitiesAndRegionsWithinRadiusResult(cityAndRegionNames: List<String>) fun onError(errorMessage: String) } fun getLastLocation(callback: LocationCallback) { GlobalScope.launch { try { val location = retrieveLastLocation() withContext(Dispatchers.Main) { callback.onLocationResult(location) } } catch (e: Exception) { withContext(Dispatchers.Main) { callback.onError("Error while retrieving location: ${e.message}") } } } } private suspend fun retrieveLastLocation(): Location? { if (ContextCompat.checkSelfPermission(context, locationPermission) == PackageManager.PERMISSION_GRANTED) { if (LocationUtils.isLocationEnabled(context)) { return try { fusedLocationClient.lastLocation.await() } catch (exception: Exception) { throw Exception("Error while retrieving location: ${exception.message}") } } else { throw Exception("Location services are not enabled.") } } throw Exception("Location permission not granted.") } fun getCitiesAndRegionsWithinExtendedRadius(location: Location, extendedRadiusKm: Double, callback: LocationCallback) { GlobalScope.launch { try { val cityAndRegionNames = lookupCitiesAndRegions(location, extendedRadiusKm) withContext(Dispatchers.Main) { callback.onCitiesAndRegionsWithinRadiusResult(cityAndRegionNames.distinct()) } } catch (e: Exception) { withContext(Dispatchers.Main) { callback.onError("Error while looking up cities: ${e.message}") } } } } private suspend fun lookupCitiesAndRegions(location: Location, extendedRadiusKm: Double): List<String> { val maxRadius = 50000.0 // Maximum radius in meters (50 km) val centerAndroid = AndroidLatLng(location.latitude, location.longitude) // 转换为Google Maps服务SDK的LatLng类型 val centerGoogle = GoogleMapsLatLng(location.latitude, location.longitude) val geoContext = GeoApiContext.Builder().apiKey(apiKey).build() val cityAndRegionNames = mutableListOf<String>() var currentRadiusMeters = 0.0 while (currentRadiusMeters < extendedRadiusKm * 1000) { val remainingRadiusMeters = min(maxRadius, (extendedRadiusKm * 1000 - currentRadiusMeters)) val bounds = getGoogleMapsBounds(centerAndroid, remainingRadiusMeters) // 使用正确的locationRestriction方法设置边界 val placesRequest = PlacesApi.nearbySearchQuery(geoContext, centerGoogle) .radius(remainingRadiusMeters.toInt()) .locationRestriction(bounds) try { val placesResult = placesRequest.await() for (result: PlacesSearchResult in placesResult.results) { for (type in result.types) { if (type == "locality" || type == "administrative_area_level_1") { cityAndRegionNames.add(result.name) break } } } } catch (e: Exception) { throw Exception("Error while looking up cities: ${e.message}") } currentRadiusMeters += maxRadius } return cityAndRegionNames } // 生成Google Maps服务SDK所需的LatLngBounds private fun getGoogleMapsBounds(center: AndroidLatLng, radiusMeters: Double): GoogleMapsLatLngBounds { val latLngPerMeter = 1.0 / 111319.9 // 1米对应的经纬度近似值 val latLngRadius = radiusMeters * latLngPerMeter val southwest = GoogleMapsLatLng(center.latitude - latLngRadius, center.longitude - latLngRadius) val northeast = GoogleMapsLatLng(center.latitude + latLngRadius, center.longitude + latLngRadius) return GoogleMapsLatLngBounds.newInstance(southwest, northeast) } }
关键修复点
- 类别名区分:给两个不同包的
LatLng/LatLngBounds设置别名,彻底避免类型混淆。 - 类型适配转换:将Android SDK的地理位置对象转换为Google Maps服务SDK的对应类型,满足Places API参数要求。
- API方法修正:把错误的
.bounds()调用替换为官方文档指定的.locationRestriction()方法。 - 边界生成调整:修改边界计算方法,直接生成Places API所需的
LatLngBounds对象。
内容的提问来源于stack exchange,提问作者Martim Fernandes
相关产品推荐
相关产品推荐

