Android开发:调用addOnPermissionsChangeListener遇权限缺失异常如何解决?
调用addOnPermissionsChangeListener触发SecurityException的解决方案
问题原因
你遇到的SecurityException核心原因是:android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS是系统级受保护权限,其protectionLevel为signature|privileged,仅系统预装应用或与系统签名一致的应用才能获取。普通第三方应用无法通过常规权限声明拿到该权限,而你调用的Google Play Services中addOnPermissionsChangeListener方法内部依赖此权限,因此触发异常。
错误栈及依赖配置:
java.lang.SecurityException: addOnPermissionsChangeListener: Neither user 10017 nor current process has android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS. at android.os.Parcel.readException(Parcel.java:2013) at android.os.Parcel.readException(Parcel.java:1959) at com.google.android.gms.common.internal.zzac.getService(com.google.android.gms:play-services-basement@@18.1.0:9) at com.google.android.gms.common.internal.BaseGmsClient.getRemoteService(com.google.android.gms:play-services-basement@@18.1.0:14) at com.google.android.gms.common.internal.BaseGmsClient$LegacyClientCallbackAdapter.onReportServiceBinding(com.google.android.gms:play-services-basement@@18.1.0:2) at com.google.android.gms.common.internal.zzg.zzd(com.google.android.gms:play-services-basement@@18.1.0:1) at com.google.android.gms.common.internal.zza.zza(com.google.android.gms:play-services-basement@@18.1.0:4) at com.google.android.gms.common.internal.zzc.zze(com.google.android.gms:play-services-basement@@18.1.0:3) at com.google.android.gms.common.internal.zzb.handleMessage(com.google.android.gms:play-services-basement@@18.1.0:31) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6518) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
依赖配置:
implementation 'com.google.android.gms:play-services-basement:18.1.0'
解决方法
方法一:使用Android原生权限监听替代
放弃Google Play Services的addOnPermissionsChangeListener,改用Android系统原生的PackageManager.addOnPermissionsChangeListener——这个方法不需要特殊权限,第三方应用可正常使用:
示例代码(Kotlin):
import android.content.pm.PackageManager import android.os.Bundle import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { private var permissionChangeListener: PackageManager.OnPermissionsChangeListener? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val packageManager = packageManager permissionChangeListener = PackageManager.OnPermissionsChangeListener { permissions -> // 遍历变化的权限,处理业务逻辑 permissions.forEach { permissionInfo -> when (permissionInfo.permission) { android.Manifest.permission.CAMERA -> { val hasPermission = packageManager.checkPermission(permissionInfo.permission, packageName) == PackageManager.PERMISSION_GRANTED // 根据权限状态执行对应操作 } // 可添加其他需要监听的权限 } } } packageManager.addOnPermissionsChangeListener(permissionChangeListener) } override fun onDestroy() { super.onDestroy() // 移除监听避免内存泄漏 permissionChangeListener?.let { packageManager.removeOnPermissionsChangeListener(it) } } }
方法二:排查GMS版本兼容性(非根本解决)
如果必须使用GMS相关方法,可尝试升级play-services-basement到最新稳定版本,排查是否存在版本兼容性问题,但注意这无法绕过系统权限限制,仅作为辅助排查手段。
修改依赖:
implementation 'com.google.android.gms:play-services-basement:latest-version'
(注:将latest-version替换为当前最新稳定版本号)
关键说明
- 不要在
AndroidManifest.xml中声明android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,系统会直接忽略该声明,普通应用无法获取此权限。 - 原生监听方法是第三方应用实现权限变化监听的唯一合法途径。
内容的提问来源于stack exchange,提问作者Francisco Javier Ramirez Ayala
相关产品推荐
相关产品推荐

