• Android权限管理知识学习记录



    一、Android权限背景知识

      在Android 6.0之前,所申请的权限只需要在AndroidManifest.xml列举就可以了,从而容易导致一些安全隐患,因此,在Android 6.0时,Google为了更好的保护用户隐私提出了新的权限管理机制,同时将其分为两大类:
    (1)Normal Permissions
      Normal Permission一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动,访问网络等。
    (2)Dangerous Permission
      Dangerous Permission一般是涉及到用户隐私的,需要用户进行授权(动态申请),比如读取SIM卡状态、访问通讯录、SD卡读写等。
      通过adb shell pm list permission -d -g可以查看Dangerous Permission。
      Dangerous Permission一般以Permission group形式存在,只要Permission Group中某一个permission被Granted(授予),则整个Permission group下的权限均被Granted。

    二、权限检查及权限兼容

    1.targetSdkVersion>=23,终端设备是6.0(api 23)以上系统。

      安装的时候不会获得权限,在运行时向用户申请对应权限。这部分权限检查比较简单,不涉及权限兼容,使用官方方案就可以,使用Context:checkSelfPermission,建议使用ContextCompat:checkSelfPermission检查权限即可,一般检查流程如下:
      (1)判断是否有对应权限
        (ContextCompat::checkSelfPermision)
      (2)判断是否需要解释对应权限用途(ActivityCompat::shouldShowRequestPermissionRationale)
        如果需要解释,则显示自定义权限界面即可
      (3)不需要解释的话,直接请求对应权限
        (ActivityCompat::requestPermission)

    2.targetSdkVersion<23.终端设备是6.0(api 23)以上系统

      使用的是老的权限机制,在app安装时会询问AndroidManifest.xml文件中的权限,但是用户可以在设置列表中关闭相关权限,这种情况可能会对app正常运行造成一定影响。

    3.终端设备系统小于6.0(api 23)

      老的权限管理机制是,在app安装时会询问AndroidManifest.xml文件中的权限,用户关闭不了,但是目前有不少国产Rom手机在6.0之间就有关闭权限的开关。
    适配过程:
    1.使用try-catch来检查权限是否关闭
      使用READ_PHONE_STATE权限的方法内部已经try-catch,外面无法捕获,所以如果该权限被用户禁止了,报异常时,在catch中做文章的方法根本没有用。
    2.ContextCompat::checkSelfPermission
      在6.0可以使用Context::checkSelfPermission进行权限检查,在api 23那使用support v4中的ContextCompat::checkSelfPermission方法失效,只要权限在AndroidManifest.xml中注册过,均会认为该权限granted,因此方法在api 23以下失效。
    3.PermissionChecker
      PermissionChecker内部实际上使用的是AppOpsManagerCompat,而AppOpsManager是在api 19加入进去的。
      在api 23以下,AppOpsManagerImpl::permissionToOp直接返回为null,这直接导致api 23以下权限检查将会返回granted,因此,该方法在api 23下,权限检查方法也会失效。
    4.AppOpsManager
      API 19以上,Google官方提供了AppOpsManager类来检查权限,里面有两个比较重要的方法:    AppOpsManager::checkOp(int op,int uid,String packageName)(hide方法,需要反射)和AppOpsManager::checkOp(String op,int uid,String packageName)(public方法,api 23以上可用)。
      但是,当api低于23时,OP_READ_PHONE_STATE=51找不到,导致AppOpsManager::checkOp方法反射失败,导致的原因是每个版本的_NUM_OP不同,OP_READ_PHONE_STATE = 51在6.0(API 23)以下,通过反射是找不到的,因此对于READ_PHONE_STATE权限检查仅限于6.0及6.0以上。

    三、跳转到app管理权限界面

    1.直接跳转系统设置页

            Intent intent = new Intent();
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.fromParts("package",getPackageName(), null));
    
            try {
                startActivity(intent);
            }catch (Exception e){
                e.printStackTrace();
            }

      记得要添加try-catch,不加可能会crash(崩溃)。这种方式就不需要适配各个厂商的不同版本rom,缺点是,用户只能跳转到系统设置页,然后去找对应app的权限管理。

    2.站在前人的肩

      对于不同的手机或手机系统,跳转权限管理页面的activity或者有所不同,如果没有加上try-catch,就会直接crash。
      对于这种变化,作为开发者一般都是不知道的,即便通过反馈发现了这个问题,也有可能不知道actiivty是什么,此刻要么搜索网上有没有类似解决方案,要么求助于对应rom开发厂商的开发者论坛。

    3.查看某个rom的某个版本的权限管理界面的activity

    (1)通过设置找到对应app的权限管理页面
    (2)找到对应页面的activity
      方法一:通过add工具查看栈顶Activity

    adb shell dumpsys activity | grep "mFocusedActivity"

      方法二:使用Activity Tracer工具

    本文只是将看到的文章进行了学习整理记录,详细的还请查看原文。


    原文:http://mp.weixin.qq.com/s/OQRHEufCUXBA3d3DMZXMKQ

  • 相关阅读:
    3.java开发环境配置
    2.java主要特性
    1.java中main函数理解
    测试项目团队角色岗位职责
    单身程序员
    软件测评师考试
    vue父子组件通信
    python偏函数使用
    Numpy+Pandas读取数据
    chrome无界面模式headless配置
  • 原文地址:https://www.cnblogs.com/zhangmiao14/p/7427855.html
Copyright © 2020-2023  润新知