如何在不使用Places API的Android应用中通过地址获取LatLng
不用Google Places API获取地址对应LatLng的可行方案
当然有办法啦!不用Google Places API的话,你可以试试这几个实用方案:
1. 用Android原生Geocoder类(最省心)
这是Android框架自带的地理编码工具,不需要额外申请API密钥,也不用调用外部服务,直接就能用。
简单示例代码(Kotlin)
// 一定要在后台线程执行,别阻塞主线程哦 val geocoder = Geocoder(context, Locale.getDefault()) try { // 第二个参数是返回结果的最大数量,填1就够了 val addressList = geocoder.getFromLocationName("你要搜索的地址", 1) if (addressList.isNotEmpty()) { val targetAddress = addressList[0] val latLng = LatLng(targetAddress.latitude, targetAddress.longitude) // 搞定!这里拿到了对应的经纬度 } else { // 没找到匹配的地址,可能是输入太模糊啦 } } catch (e: IOException) { // 处理网络或者服务不可用的异常,比如设备没联网 }
注意点
- 有些小众设备或者地区可能对
Geocoder支持不好,会返回空结果; - 必须在后台线程调用,不然会触发
NetworkOnMainThreadException; - 如果地址太宽泛(比如只输入“北京市”),可能会返回多个结果,记得限制数量或者让用户进一步筛选。
2. 调用开源地理编码服务的REST接口(兼容性更强)
如果Geocoder不好用,你可以试试OpenStreetMap旗下的Nominatim服务,通过HTTP请求就能获取经纬度,完全免费开源。
简单示例代码(Kotlin + OkHttp + Gson)
// 同样要在后台线程执行哦 val targetAddress = URLEncoder.encode("你要搜索的地址", "UTF-8") // 构造请求URL,limit=1表示只返回最匹配的结果 val requestUrl = "https://nominatim.openstreetmap.org/search?q=$targetAddress&format=json&limit=1" // 用OkHttp发起GET请求 val client = OkHttpClient() val request = Request.Builder().url(requestUrl).build() client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { // 处理网络请求失败的情况 } override fun onResponse(call: Call, response: Response) { response.body?.string()?.let { responseStr -> // 用Gson解析返回的JSON数据 val results = Gson().fromJson(responseStr, Array<NominatimResult>::class.java) if (results.isNotEmpty()) { val lat = results[0].lat.toDouble() val lon = results[0].lon.toDouble() val latLng = LatLng(lat, lon) // 成功拿到经纬度,记得切回主线程更新UI哦 } } } }) // 对应的实体类,用来解析JSON data class NominatimResult(val lat: String, val lon: String)
注意点
- 要遵守Nominatim的使用规则:不要频繁发起请求(建议每秒不超过1次),商用的话最好提前查看它的使用条款;
- 记得给地址做URL编码,避免特殊字符(比如空格、中文)导致请求失败;
- 要处理网络异常、JSON解析异常这些情况,避免崩溃。
额外小建议
你可以把两种方案结合起来:先尝试用Geocoder,如果返回空结果或者抛出异常,再调用Nominatim作为备用方案,这样兼容性会更好~
内容的提问来源于stack exchange,提问作者Sabahat Yaqoob
相关产品推荐
相关产品推荐

