我是否应该更喜欢使用ContextCompat或PermissionChecker进行Android权限检查?

时间:2017-06-28 23:12:39

标签: android android-support-library

我可以选择以下任一方式检查我的应用是否具有给定的权限。

哪一个更受欢迎?

ContextCompat(来自support-compat lib):

ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)

PermissionChecker(来自support-core-utils lib):

PermissionChecker.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)

请注意(截至25.3.1)-core-utils取决于-compat:

| | +--- com.android.support:support-core-utils:25.3.1 | | | +--- com.android.support:support-annotations:25.3.1 | | | \--- com.android.support:support-compat:25.3.1 (*)

2 个答案:

答案 0 :(得分:10)

进入PermissionChecker的来源,我们可以看到它首先调用Context#checkPermission并提前保释,如果调用代码有权限。如果调用代码确实拥有权限,则会转到神秘的AppOpsManager询问我们是否permissionToOp,然后检查noteProxyOp的返回。这提供了一个关于此方法的用途的提示,因为noteProxyOp的文档以:

开头
  

记录在处理IPC时代表另一个应用程序执行操作的应用程序。

此外,如果我们检查PermissionChecker方法的返回值,我们会看到有三种可能结果之一:

  

权限检查结果为PERMISSION_GRANTEDPERMISSION_DENIEDPERMISSION_DENIED_APP_OP

即0,-1或-2返回值。此类似乎适用于接收进程间通信并代表其他应用程序执行操作的应用程序。

另一方面,

ContextCompat只需抓取当前进程ID并直接返回Context#checkPermission的结果:

  

PERMISSION_GRANTED如果给定的pid / uid允许该权限,或PERMISSION_DENIED如果不允许,则为<{1}}。

因此,对于大多数编写标准Android应用的开发者而言,使用ContextCompat

答案 1 :(得分:2)

由于文档和可用教程的质量,我将使用ContextCompat 但我在下面的地方读到了以下内容: 如果您的设备在Android M及更高版本上运行且targetSdkVersion低于22,则两者之间会略有不同。
第一次将设备权限设置为关闭时启动应用程序时,行为如下:

  1. ContextCompat:始终返回GRANTED
  2. PermissionChecker:返回GRANTED或PERMISSION_DENIED_APP_OP
  3. 使用此PermissionChecker可能更明智,但再次实现运行时权限,您需要将targetSdkVersion设置为23或更高。