6.0+授权管理,工作中一直在用,但是大部分是直接使用RxPermission, XXPermission等第三方的github三方库,也偷懒没有了解原生实现,今天翻了下文档,发现原生实现也是异常简单,这里mark下,做个备忘

部分引用自 《在运行时请求权限》,做了精简,只取了关键解释内容,可以使用下面地址查看原文,自备梯子
https://developer.android.com/training/permissions/requesting

1、概述

从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予。此方法可以简化应用安装过程,因为用户在安装或更新应用时不需要授予权限。它还让用户可以对应用的功能进行更多控制;例如,用户可以选择为相机应用提供相机访问权限,而不提供设备位置的访问权限。用户可以随时进入应用的“Settings”屏幕调用权限。

系统权限分为两类:正常权限危险权限

  • 正常权限不会直接给用户隐私权带来风险。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。

  • 危险权限会授予应用访问用户机密数据的权限。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。如果您列出了危险权限,则用户必须明确批准您的应用使用这些权限。

2、主要的方法

  • public static int checkSelfPermission(@NonNull Context context, @NonNull String permission)

主要用到的就是这四个方法了。

要检查您是否具有某项权限,请调用 ContextCompat.checkSelfPermission()方法,。例如,以下代码段显示了如何检查 Activity 是否具有在日历中进行写入的权限:

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.WRITE_CALENDAR);

如果应用具有此权限,方法将返回 PackageManager.PERMISSION_GRANTED,并且应用可以继续操作。如果应用不具有此权限,方法将返回PERMISSION_DENIED,且应用必须明确向用户要求权限。

  • public static boolean shouldShowRequestPermissionRationale(@NonNull Activity activity, @NonNull String permission)

在获取授权的时候,可能需要向用户解释为什么需要用户授权,这时候就需要用到shouldShowRequestPermissionRationale方法了,如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。

注:如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don’t ask again 选项,此方法将返回 false。如果设备规范禁止应用具有该权限,此方法也会返回 false。

  • public static void requestPermissions(@NonNull final Activity activity, @NonNull final String[] permissions, @IntRange(from = 0L) final int requestCode)

如果应用尚无所需的权限,则应用必须调用一个requestPermissions()方法,以请求适当的权限。应用将传递其所需的权限,以及您指定用于识别此权限请求的整型请求代码。此方法异步运行:它会立即返回,并且在用户响应对话框之后,系统会使用结果调用应用的回调方法,将应用传递的相同请求代码传递到requestPermissions()

注:当您的应用调用 requestPermissions() 时,系统将向用户显示一个标准对话框。您的应用无法配置或更改此对话框。如果您需要为用户提供任何信息或解释,您应在调用 requestPermissions() 之前进行,如解释应用为什么需要权限中所述。

  • public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)

当应用请求权限时,系统将向用户显示一个对话框。当用户响应时,系统将调用应用的 onRequestPermissionsResult()方法,向其传递用户响应。您的应用必须替换该方法,以了解是否已获得相应权限。回调会将您传递的相同请求代码传递给 requestPermissions()

3、实例

这里有个知识点,授权的时候存在一个权限组的概念,比如Manifest.permission.WRITE_EXTERNAL_STORAGE和Manifest.permission.READ_EXTERNAL_STORAGE这两个权限就是可以看成一组权限,不需要分别两个都授权,只需要授权一个,另一个权限也就相应的获得了。

3-1、获取单个权限
 if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)
     != PackageManager.PERMISSION_GRANTED) {
    if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.CAMERA)) {
        Log.i("info", "需要使用到该权限");
        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 100);
    } else {
        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 100);
    }
} else {
    Log.i("info", "已经授权");
}
3-2、获取多个权限
final List<String> permissionList = new ArrayList<>();
 permissionList.clear();

String[] permissions = {
        Manifest.permission.CAMERA,
        Manifest.permission.WRITE_EXTERNAL_STORAGE,
        Manifest.permission.READ_CONTACTS
};
for (int i = 0; i < permissions.length; i++) {
    if (ContextCompat.checkSelfPermission(MainActivity.this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
        permissionList.add(permissions[i]);
    }
}
if (permissionList.size() > 0) {
    ActivityCompat.requestPermissions(MainActivity.this, permissions, 200);
}

4、危险权限和权限组

在这里插入图片描述
在这里插入图片描述

5、其他问题

用户点击不再提醒处理

Android6.0运行时权限封装(避免用户选择不再提示后无法获取权限的问题)
https://www.jianshu.com/p/db3911bcedab

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐