返回

解密Android权限申请流程,打造严谨安全APP

Android

Android权限申请机制概述

Android 6.0 开始引入权限申请机制,将所有权限分为了正常权限和危险权限。App每次在使用危险权限时需要动态的申请并得到用户的授权才能使用,否则会抛出异常。那么权限申请、校验又是如何实现的呢?这也是我们这篇笔记的要分析的重点。

权限分类

系统权限分为两类:

  • 正常权限 :App 默认拥有此类权限,无需向用户申请,也不需要声明在清单文件中。

  • 危险权限 :App 需要在使用时向用户申请,并且需要在清单文件中声明。常见的危险权限包括:

    • 读取设备位置信息(android.permission.ACCESS_FINE_LOCATION)
    • 读取联系人信息(android.permission.READ_CONTACTS)
    • 拨打电话(android.permission.CALL_PHONE)
    • 读写SD卡(android.permission.WRITE_EXTERNAL_STORAGE)
    • 使用相机(android.permission.CAMERA)

权限申请

App 在需要使用危险权限时,需要通过以下步骤向用户申请:

  1. 在清单文件中声明需要申请的危险权限。
  2. 在运行时使用 requestPermissions() 方法向用户申请权限。
  3. onRequestPermissionsResult() 方法中处理用户的授权结果。

以下代码演示了如何申请危险权限:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_CODE_READ_CONTACTS);
}

onRequestPermissionsResult() 方法中,App 可以根据用户的授权结果采取不同的操作:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_CODE_READ_CONTACTS && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        // 用户同意授权
    } else {
        // 用户拒绝授权
    }
}

权限校验

在获得用户的授权后,App 就可以使用危险权限了。但在使用之前,App 需要再次校验权限是否已经被授予。这可以通过以下代码实现:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
    // 权限已经被授予
} else {
    // 权限没有被授予
}

如果权限没有被授予,App 应该提示用户授予权限,或者采取其他措施来处理这种情况。

系统权限申请机制的底层实现

Android 系统权限申请机制的底层实现主要涉及以下几个类:

  • PackageManager :负责管理App的权限。
  • PermissionChecker :负责检查App是否拥有某个权限。
  • onRequestPermissionsResult() 方法:负责处理用户的授权结果。

当App 调用 requestPermissions() 方法时,系统会创建一个 PermissionRequest 对象,并将它添加到 PermissionManagerService 中。PermissionManagerService 会负责向用户展示权限申请对话框。

当用户做出授权决定后,系统会将授权结果传递给 PermissionManagerServicePermissionManagerService 会将授权结果存储到 PackageManager 中。

当App 调用 checkSelfPermission() 方法时,系统会从 PackageManager 中获取权限信息。如果App拥有该权限,则返回 PackageManager.PERMISSION_GRANTED;否则,返回 PackageManager.PERMISSION_DENIED

当App 调用 onRequestPermissionsResult() 方法时,系统会将授权结果传递给该方法。App 可以根据授权结果采取不同的操作。

结语

Android 权限申请机制旨在保护用户隐私和安全。通过合理使用权限申请机制,App 可以确保自己不会滥用用户数据和隐私。