切换新版Google Maps SDK时出现迁移错误求助
解决Places SDK迁移中PLACE_DETECTION_API和GeoDataApi的错误问题
看起来你遇到的核心问题是旧版Places API(基于GoogleApiClient的GEO_DATA_API和PLACE_DETECTION_API)在新版Places SDK中已经被完全废弃,虽然你初始化了新的PlacesClient,但代码里还在混用旧的API调用,导致报错。下面是一步步的解决方案:
1. 清理依赖,避免版本冲突
首先,你可以移除旧的play-services-places依赖,因为新版的com.google.android.libraries.places:places已经完全替代了它,保留会导致冲突:
dependencies { //noinspection GradleCompatible implementation 'com.github.bumptech.glide:glide:4.9.0' implementation 'com.google.android.gms:play-services-maps:17.0.0' implementation 'com.google.android.gms:play-services-location:17.0.0' // 移除这行旧依赖,避免版本冲突 // implementation 'com.google.android.gms:play-services-places:17.0.0' implementation 'com.google.android.libraries.places:places:2.1.0' implementation 'com.google.android.libraries.places:places-compat:2.1.0' }
2. 彻底移除旧的GoogleApiClient相关代码
旧版的GoogleApiClient、Places.GEO_DATA_API、PLACE_DETECTION_API以及对应的回调接口(ConnectionCallbacks、OnConnectionFailedListener)都要完全删掉,包括:
mGoogleApiClient的初始化代码onConnected方法- Activity实现的
GoogleApiClient相关接口
3. 使用新版PlacesClient实现自动完成预测
替换原来的getAutocompletePredictions调用,改用新版API的异步方法:
保留已完成的PlacesClient初始化
// 在Activity的onCreate中 String apiKey = "你的API密钥"; Places.initialize(getApplicationContext(), apiKey); PlacesClient placesClient = Places.createClient(this); // 可以把placesClient设为全局变量,方便后续调用
获取自动完成预测(替换旧的AsyncTask和onConnected逻辑)
// 示例:搜索"infopark"的预测结果 AutocompletePredictionRequest predictionRequest = AutocompletePredictionRequest.builder() .setQuery("infopark") // 可选:添加位置限制,比如只搜索特定国家 // .setCountry("IN") // 可选:设置位置边界,缩小搜索范围 // .setLocationRestriction(RectangularBounds.newInstance(...) .build(); placesClient.findAutocompletePredictions(predictionRequest) .addOnSuccessListener(response -> { // 处理预测结果 Log.i(TAG, "收到" + response.getAutocompletePredictions().size() + "条预测"); for (AutocompletePrediction prediction : response.getAutocompletePredictions()) { Log.i(TAG, "地点ID:" + prediction.getPlaceId()); Log.i(TAG, "主名称:" + prediction.getPrimaryText(null)); Log.i(TAG, "地址:" + prediction.getSecondaryText(null)); } // 把预测结果传给RecyclerView适配器更新UI }) .addOnFailureListener(exception -> { if (exception instanceof ApiException) { ApiException apiException = (ApiException) exception; Log.e(TAG, "获取预测失败,错误码:" + apiException.getStatusCode()); } });
4. 替换获取Place详情的代码
在SearchResultsRecycler的点击事件中,把旧的Places.GeoDataApi.getPlaceById替换成新版的fetchPlace方法:
itemView.setOnClickListener(v -> { AutocompletePrediction item = mResultList.get(getLayoutPosition()); String placeId = item.getPlaceId(); // 定义需要获取的Place字段(按需添加,避免请求不必要的字段) List<Place.Field> placeFields = Arrays.asList( Place.Field.ID, Place.Field.NAME, Place.Field.ADDRESS, Place.Field.LAT_LNG ); FetchPlaceRequest fetchPlaceRequest = FetchPlaceRequest.builder(placeId, placeFields).build(); // 建议通过Adapter构造方法传入PlacesClient,或者从Context强转Activity获取 ((SearchActivity) v.getContext()).getPlacesClient().fetchPlace(fetchPlaceRequest) .addOnSuccessListener(response -> { Place place = response.getPlace(); Log.i(TAG, "获取到地点详情:" + place.getName() + ",地址:" + place.getAddress()); // 这里处理选中地点后的逻辑,比如跳转到地图页面 }) .addOnFailureListener(exception -> { if (exception instanceof ApiException) { ApiException apiException = (ApiException) exception; Log.e(TAG, "获取地点详情失败,错误码:" + apiException.getStatusCode()); } }); });
关键注意点
- 新版Places SDK的所有API都是异步的,不需要自己用
AsyncTask处理后台线程,SDK内部会管理线程。 - 确保在Google Cloud控制台中启用的是新版Places API,而不是旧的
Places SDK for Android。 - 检查API密钥的权限,确保它绑定了正确的包名和SHA-1,并且拥有Places API的调用权限。
按照上面的步骤替换代码后,旧的PLACE_DETECTION_API和GeoDataApi相关错误就会消失,新版API就能正常工作了。
内容的提问来源于stack exchange,提问作者Sujit Maiti




