美文网首页
Android运行时动态申请权限

Android运行时动态申请权限

作者: 古早味蛋糕 | 来源:发表于2022-08-21 23:42 被阅读0次

    在以前App若想访问存储卡的公共空间,就要在AndroidManifest.xml里面添加下述的权限配置:


    per1.png

    然而现在即使App声明了完整的存储卡操作权限,从Android 7.0开始,系统仍然默认禁止该App访问公共空间,必须到设置界面手动开启应用的存储卡权限才行。尽管此举是为用户隐私着想,可是人家咋知道要手工开权限呢?就算用户知道,去设置界面找到权限开关也颇费周折。为此Android支持在Java代码中处理权限,处理过程分为3个步骤,详述如下:
    1.检查App是否开启了指定权限权限检查需要调用ContextCompat的checkSelfPermission方法,该方法的第一个参数为活动实例,第二个参数为待检查的权限名称,例如存储卡的写权限名为Manifest.permission.WRITE_EXTERNAL_STORAGE。注意checkSelfPermission方法的返回值,当它为PackageManager.PERMISSION_GRANTED时表示已经授权,否则就是未获授权。
    2.请求系统弹窗,以便用户选择是否开启权限一旦发现某个权限尚未开启,就得弹窗提示用户手工开启,这个弹窗不是开发者自己写的提醒对话框,而是系统专门用于权限申请的对话框。调用ActivityCompat的requestPermissions方法,即可命令系统自动弹出权限申请窗口,该方法的第一个参数为活动实例,第二个参数为待申请的权限名称数组,第三个参数为本次操作的请求代码。
    3.判断用户的权限选择结果然而上面第二步的requestPermissions方法没有返回值,那怎么判断用户到底选了开启权限还是拒绝权限呢?其实活动页面提供了权限选择的回调方法onRequestPermissionsResult,如果当前页面请求弹出权限申请窗口,那么该页面的Java代码必须重写onRequestPermissionsResult方法,并在该方法内部处理用户的权限选择结果。具体到编码实现上,前两步的权限校验和请求弹窗可以合并到一块,先调用checkSelfPermission方法检查某个权限是否已经开启,如果没有开启再调用requestPermissions方法请求系统弹窗。合并之后的检查方法代码示例如下,此处代码支持一次检查一个权限,也支持一次检查多个权限;

    public class PermissionUtil {
    
     // 检查多个权限。返回true表示已完全启用权限,返回false表示未完全启用权限
     public static boolean checkPermission(Activity act, String[] permissions, int requestCode) {
        // Android 6.0 之后开始采用动态权限管理
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int check = PackageManager.PERMISSION_GRANTED;
            for (String permission : permissions) {
                check = ContextCompat.checkSelfPermission(act, permission);
                if (check != PackageManager.PERMISSION_GRANTED) {
                    break;
                }
            }
            // 未开启该权限,则请求系统弹窗,好让用户选择是否立即开启权限
            if (check != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(act, permissions, requestCode);
                return false;
            }
        }
        return true;
    }
    
     // 检查权限结果数组,返回true表示都已经获得授权。返回false表示至少有一个未获得授权
     public static boolean checkGrant(int[] grantResults) {
        if (grantResults != null) {
            // 遍历权限结果数组中的每条选择结果
            for (int grant : grantResults) {
                // 未获得授权
                if (grant != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
            return true;
        }
        return false;
      }
    }
    

    注意到上面代码有判断安卓版本号,只有系统版本大于Android 6.0(版本代号为M),才执行后续的权限校验操作。这是因为从Android 6.0开始引入了运行时权限机制,在Android 6.0之前,只要App在AndroidManifest.xml中添加了权限配置,则系统会自动给App开启相关权限;但在Android 6.0之后,即便事先添加了权限配置,系统也不会自动开启权限,而要开发者在App运行时判断权限的开关情况,再据此动态申请未获授权的权限。

    相关文章

      网友评论

          本文标题:Android运行时动态申请权限

          本文链接:https://www.haomeiwen.com/subject/lfnvgrtx.html