返回

6.0 权限 —— 源码解读 Activity.requestPermissions()

Android

Android 权限管理的基石:Activity.requestPermissions()

权限在 Android 系统中的关键作用

Android 系统中,权限机制是保障应用安全性和用户隐私的关键。它赋予应用访问设备资源(如摄像头、麦克风、存储空间等)的权利。然而,滥用权限的后果不堪设想,轻则数据泄露,重则恶意软件攻击。因此,Android 系统对权限管理有着严格规定,并不断完善相关机制以保护用户利益。

Activity.requestPermissions() 的作用

Activity.requestPermissions() 是 Android 系统提供的 API,用于向用户请求权限。当应用需要使用特定权限时,便可通过此方法向用户申请授权。若用户同意,应用即可获取权限并继续操作;若用户拒绝,应用则无法获得权限,需采取其他措施完成操作。

Activity.requestPermissions() 的内部机制

深入源码,逐行分析 Activity.requestPermissions() 的内部运作原理:

public void requestPermissions(@NonNull String[] permissions, int requestCode) {
    // 检查权限是否合法
    if (permissions == null) {
        throw new IllegalArgumentException("Permission request for null permissions");
    }
    if (requestCode < 0) {
        throw new IllegalArgumentException("requestCode < 0: " + requestCode);
    }

    // 获取 FragmentManager
    FragmentManager fragmentManager = getFragmentManager();
    if (fragmentManager == null) {
        throw new IllegalStateException("This Activity has no FragmentManager");
    }

    // 创建 FragmentRequestPermissions 对象
    FragmentRequestPermissions fragment = new FragmentRequestPermissions(permissions, requestCode);

    // 将 FragmentRequestPermissions 对象添加到 FragmentManager
    fragmentManager.beginTransaction().add(fragment, "android:fragment:request_permissions").commitNowAllowingStateLoss();
}

首先,我们检查请求的权限是否合法,确保权限不为空且请求码大于等于 0。随后,获取当前 Activity 的 FragmentManager,它负责管理 Fragment,进而管理 FragmentRequestPermissions 对象。接下来,创建一个 FragmentRequestPermissions 对象,并将其添加到 FragmentManager 中。这个对象负责实际的权限请求工作,处理用户对权限的授权或拒绝。

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    // 检查请求码是否合法
    if (requestCode < 0) {
        throw new IllegalArgumentException("requestCode < 0: " + requestCode);
    }

    // 获取请求的权限
    String[] requestPermissions = getRequestPermissions(requestCode);

    // 检查请求的权限是否合法
    if (requestPermissions == null) {
        throw new IllegalArgumentException("Request permissions for requestCode " + requestCode + " were not found.");
    }

    // 检查请求的权限数量是否与实际返回的授权结果数量一致
    if (requestPermissions.length != permissions.length) {
        throw new IllegalArgumentException("Length of request permissions and granted permissions arrays must match.");
    }

    // 检查请求的权限数量是否与实际返回的授权结果数量一致
    if (requestPermissions.length != grantResults.length) {
        throw new IllegalArgumentException("Length of request permissions and granted results arrays must match.");
    }

    // 调用回调函数,通知用户权限申请的结果
    dispatchRequestPermissionsResult(requestCode, requestPermissions, grantResults);

    // 移除 FragmentRequestPermissions 对象
    FragmentManager fragmentManager = getFragmentManager();
    if (fragmentManager != null) {
        FragmentRequestPermissions fragment = (FragmentRequestPermissions) fragmentManager.findFragmentByTag("android:fragment:request_permissions");
        if (fragment != null) {
            fragmentManager.beginTransaction().remove(fragment).commitAllowingStateLoss();
        }
    }
}

当用户对权限请求作出决定后,系统会调用 onRequestPermissionsResult() 方法。这个方法负责处理权限申请的结果。首先,我们检查请求码是否合法,确保请求码大于等于 0。随后,获取请求的权限并检查其是否合法。接下来,检查请求的权限数量是否与实际返回的授权结果数量一致。最后,我们调用回调函数,通知用户权限申请的结果,并移除 FragmentRequestPermissions 对象。

正确使用 Activity.requestPermissions()

使用 Activity.requestPermissions() 时,我们需要遵循以下步骤:

  1. 确认应用是否需要该权限。
  2. 调用 Activity.requestPermissions() 方法向用户请求权限。
  3. 在 onRequestPermissionsResult() 方法中处理权限申请的结果。
  4. 根据用户的选择,采取相应的措施。

请求权限时,我们需要向用户提供清晰的解释,说明请求该权限的原因,并确保用户理解该权限的使用目的。此外,我们需要避免滥用权限,并妥善处理用户对权限的拒绝。

总结

Activity.requestPermissions() 是 Android 系统提供的 API,用于向用户请求权限。通过调用 Activity.requestPermissions() 方法,我们可以向用户请求授权,并根据用户的选择采取相应的措施。在使用 Activity.requestPermissions() 方法时,我们需要遵循正确的步骤,并妥善处理用户的选择。

常见问题解答

  1. 为什么在申请权限时会被拒绝?

用户拒绝权限的常见原因有:

  • 他们不了解权限的用途或含义。
  • 他们不信任应用。
  • 他们担心隐私泄露或数据滥用。
  1. 如何提高用户同意权限的可能性?
  • 在权限请求弹出窗口中提供清晰的解释和示例。
  • 在应用中使用权限时提供透明度和控制权。
  • 避免滥用权限。
  1. 如果用户拒绝权限,我该怎么办?

如果用户拒绝权限,你可以:

  • 提供一个备用选项,该选项不依赖于该权限。
  • 向用户解释权限的重要性,并尝试再次请求。
  • 在应用中添加一个设置,允许用户以后授予权限。
  1. 我可以请求多个权限吗?

可以,可以使用一个 String[] 数组来指定多个权限。

  1. 如何检查权限是否已授予?

可以使用 checkSelfPermission() 方法来检查权限是否已授予。