Android Studio中Geocoder RPC调用失败(状态码102)求助
这个Geocoder RPC 102错误我之前做地图相关项目时也碰到过,本质是系统Geocoder服务调用失败,通常和网络、权限、地址格式或者调用方式有关,给你几个针对性的解决思路:
1. 先排查基础配置与网络
- 确保你的应用已经申请并获得了
ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限,虽然官方文档没强制要求,但很多设备的Geocoder服务依赖位置权限才能正常工作。记得在运行时动态申请权限,不要只在Manifest里声明。 - 确认设备有稳定的联网状态,系统Geocoder依赖Google的在线地理编码服务,离线状态下几乎一定会失败(除非设备预先加载了离线地理数据,普通设备很少有这个配置)。可以加个网络状态检查,比如用
ConnectivityManager判断当前是否有可用网络。
2. 优化地址输入的格式
模糊或不规范的地址是触发102错误的常见原因。尽量提供结构化的完整地址,比如“XX街道 XX号,XX市,XX省,XX国”,避免只输入小区名、商圈名这类模糊内容。
你可以对输入的地址做简单预处理:去除多余空格、统一格式(比如把“北京市朝阳区XX路”这类格式标准化),能大幅提高编码成功率。
3. 修复同步调用的问题,添加重试机制
绝对不要在主线程调用getFromLocationName!这个方法是同步阻塞的,在UI线程执行很容易因为超时或线程阻塞触发RPC失败。建议把地理编码逻辑放到异步线程里,比如用ExecutorService或者AsyncTask(如果是Java项目),Kotlin的话用Coroutine更方便。
另外,临时的服务波动也会导致失败,可以加个重试逻辑,比如失败后间隔1秒重试1-2次,示例代码如下:
private LatLng getLocationFromAddressWithRetry(Context context, String inputtedAddress, int retryTimes) { Geocoder coder = new Geocoder(context); List<Address> addressList; try { // 获取最多5个匹配结果 addressList = coder.getFromLocationName(inputtedAddress, 5); if (addressList != null && !addressList.isEmpty()) { Address targetAddr = addressList.get(0); return new LatLng(targetAddr.getLatitude(), targetAddr.getLongitude()); } } catch (IOException e) { e.printStackTrace(); // 如果还有重试次数,等待后重试 if (retryTimes > 0) { try { Thread.sleep(1000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } return getLocationFromAddressWithRetry(context, inputtedAddress, retryTimes - 1); } } return null; }
调用的时候用getLocationFromAddressWithRetry(context, yourAddress, 2),最多重试2次即可,次数太多也没意义。
4. 备用方案:改用Google Maps Geocoding API
如果系统Geocoder一直不稳定,不如直接用官方的Google Maps Geocoding API,这个比系统内置的Geocoder更可靠,受设备定制系统的影响更小。
你需要先在Google Cloud控制台申请API密钥,启用Geocoding API服务,然后用OkHttp或Retrofit发送请求,示例请求格式:
https://maps.googleapis.com/maps/api/geocode/json?address=你的地址&key=你的API_KEY
解析返回的JSON就能拿到经纬度了。注意这个API有免费调用限额,如果是商用项目可能需要付费,但稳定性和兼容性都比系统Geocoder好很多。
5. 检查Google Play Services状态
系统Geocoder依赖Google Play Services提供的服务,如果设备上的Google Play Services版本过低或者未安装,也会出现RPC错误。你可以加个检查逻辑:
int resultCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context); if (resultCode != ConnectionResult.SUCCESS) { // 引导用户更新或安装Google Play Services GoogleApiAvailability.getInstance().getErrorDialog(activity, resultCode, 0).show(); }
先从前面几个基础方案排查,一般都能解决问题,如果还是不行,再考虑换成官方API。
内容的提问来源于stack exchange,提问作者Alex E.

