如何正确检测已安装的GooglePlayServices是否处于正常运行状态?
Google Play Services有效性校验修复方案
- 问题根因
官方提供的GoogleApiAvailability.isGooglePlayServicesAvailable接口仅做表层校验:仅检查GMS安装状态、版本号是否符合要求、是否被系统禁用,不会验证GMS核心服务能否正常绑定、响应请求。国内版MIUI升级后会将用户手动安装的GMS权限回收、进程冻结,但是GMS包仍保留在系统中,所以表层校验会误返回SUCCESS,实际请求时就会出现你日志里的服务绑定超时问题。 - 优化校验逻辑
在原有官方表层校验的基础上,新增10秒超时的轻量实际请求校验,确认GMS可以正常响应后再判定为可用,示例代码如下:
import kotlinx.coroutines.* import kotlinx.coroutines.tasks.await import java.util.concurrent.TimeUnit private suspend fun isGooglePlayServicesFunctional(activity: Activity): Boolean { val googleApiAvailability = GoogleApiAvailability.getInstance() val baseStatus = googleApiAvailability.isGooglePlayServicesAvailable(activity) // 基础校验不通过直接返回不可用 if (baseStatus != ConnectionResult.SUCCESS) { return false } // 新增实际连通性校验,10秒超时 return withContext(Dispatchers.Default) { val fusedLocationClient = LocationServices.getFusedLocationProviderClient(activity) return@withContext try { // 尝试拉取最后一次定位,10秒没返回直接判定失效 fusedLocationClient.lastLocation.await(10, TimeUnit.SECONDS) != null } catch (e: Exception) { false } } }
- 调整业务调用逻辑
替换原有校验方法的调用,若校验返回false直接走原生定位的兜底逻辑即可:
// 协程作用域中调用校验逻辑 lifecycleScope.launch { if (isGooglePlayServicesFunctional(this@YourActivity)) { // 原有FusedLocation相关逻辑不变 val task: Task<LocationSettingsResponse> = settingsClient.checkLocationSettings(mLocationSettingsRequest) // ... 原有成功、失败回调逻辑不变 } else { nonPlayServicesLocationManager() } }
- 额外适配国内版MIUI的补充校验
针对国内版MIUI设备,可以额外增加权限校验逻辑,检测GMS是否被授予自启动权限、后台弹出界面权限,两个权限任意一个被禁用都可以直接判定GMS无法正常工作。
内容的提问来源于stack exchange,提问作者WP7
相关产品推荐
相关产品推荐

