升级Play Services Location至21.0.0后ApiException无法转为ResolvableApiException
升级Play Services Location到21.0.0后定位设置代码修复方案
问题背景
将Google Play Services Location依赖从
implementation "com.google.android.gms:play-services-location:20.0.0"
升级到
implementation "com.google.android.gms:play-services-location:21.0.0"
后,原定位设置检查代码抛出ClassCastException,无法将ApiException强转为ResolvableApiException。
原代码片段:
LocationServices.getSettingsClient(activity) .checkLocationSettings(settingsBuilder.build()) .addOnCompleteListener { task -> try { task.getResult(ApiException::class.java) } catch (ex: ApiException) { when (ex.statusCode) { LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try { val resolvableApiException = ex as ResolvableApiException // 原处理逻辑 } catch (castEx: ClassCastException) { // 异常触发点 } } } }
抛出异常:
java.lang.ClassCastException: com.google.android.gms.common.api.ApiException cannot be cast to com.google.android.gms.common.api.ResolvableApiException
修复方案
原因说明
21.0.0版本起,checkLocationSettings返回的ApiException不再直接实现ResolvableApiException接口,需通过异常的status对象来获取可解析的跳转意图。
修复代码
替换原强转逻辑,改为判断status是否为ResolvableApiException实例:
LocationServices.getSettingsClient(activity) .checkLocationSettings(settingsBuilder.build()) .addOnCompleteListener { task -> try { task.getResult(ApiException::class.java) // 定位设置已符合要求,执行后续操作 } catch (ex: ApiException) { when (ex.statusCode) { LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> { val status = ex.status if (status is ResolvableApiException) { try { // 启动系统定位设置界面引导用户开启定位 status.startResolutionForResult(activity, REQUEST_CHECK_SETTINGS) } catch (sendEx: IntentSender.SendIntentException) { // 处理跳转失败的异常 } } else { // 无法自动跳转,提示用户手动开启定位权限或系统定位 } } LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> { // 设备不支持定位功能,提示用户 } else -> { // 处理其他定位相关异常 } } } }
AndroidX适配(推荐)
若项目使用AndroidX,建议用ActivityResultContracts替代过时的startResolutionForResult:
// 提前注册ActivityResultLauncher private val locationSettingsLauncher = registerForActivityResult( ActivityResultContracts.StartIntentSenderForResult() ) { result -> when (result.resultCode) { Activity.RESULT_OK -> { // 用户同意开启定位,执行后续逻辑 } Activity.RESULT_CANCELED -> { // 用户拒绝开启,提示相关信息 } } } // 在异常处理中调用 if (status is ResolvableApiException) { try { locationSettingsLauncher.launch( IntentSenderRequest.Builder(status.resolution.intentSender).build() ) } catch (sendEx: IntentSender.SendIntentException) { // 处理跳转异常 } }
内容的提问来源于stack exchange,提问作者user924
相关产品推荐
相关产品推荐

