• 说说Android6.0动态申请权限的那些坑


    白天在做SDK23版本的适配,遇到了不少坑,现在抽空记下来,以此为戒。

      首先要知道哪些坑,就得先了解一些定义和基本使用方式。

    那么先介绍一下动态申请的权限分组情况。

      下面的权限组是由谷歌官方定义的,目的是在申请权限时,只要用户允许同一权限组的任意一条权限,那么该组的其他权限也就默认是允许的。不过据高人介绍,在使用时最好是用到哪个权限就具体的请求该权限,因为保不齐哪天谷歌一高兴就把权限组换了甚至删了、

    group:android.permission-group.CONTACTS
      permission:android.permission.WRITE_CONTACTS
      permission:android.permission.GET_ACCOUNTS
      permission:android.permission.READ_CONTACTS
    
    group:android.permission-group.PHONE
      permission:android.permission.READ_CALL_LOG
      permission:android.permission.READ_PHONE_STATE
      permission:android.permission.CALL_PHONE
      permission:android.permission.WRITE_CALL_LOG
      permission:android.permission.USE_SIP
      permission:android.permission.PROCESS_OUTGOING_CALLS
      permission:com.android.voicemail.permission.ADD_VOICEMAIL
    
    group:android.permission-group.CALENDAR
      permission:android.permission.READ_CALENDAR
      permission:android.permission.WRITE_CALENDAR
    
    group:android.permission-group.CAMERA
      permission:android.permission.CAMERA
    
    group:android.permission-group.SENSORS
      permission:android.permission.BODY_SENSORS
    
    group:android.permission-group.LOCATION
      permission:android.permission.ACCESS_FINE_LOCATION
      permission:android.permission.ACCESS_COARSE_LOCATION
    
    group:android.permission-group.STORAGE
      permission:android.permission.READ_EXTERNAL_STORAGE
      permission:android.permission.WRITE_EXTERNAL_STORAGE
    
    group:android.permission-group.MICROPHONE
      permission:android.permission.RECORD_AUDIO
    
    group:android.permission-group.SMS
      permission:android.permission.READ_SMS
      permission:android.permission.RECEIVE_WAP_PUSH
      permission:android.permission.RECEIVE_MMS
      permission:android.permission.RECEIVE_SMS
      permission:android.permission.SEND_SMS
      permission:android.permission.READ_CELL_BROADCASTS

    其实权限组的定义很简单,下面简单介绍下动态申请权限的步骤。

    第一步,检查app拥有的权限。 

    1 if(ContextCompat.checkSelfPermission(
    2     mActivity,Manifest.permisson.READ_CONTACTS)
    3     != PackageManager.PERMISSION_GRANTED) {
    4     //当前Activity没有获得READ_CONTACTS权限时
    5 }else{
    6     //否则已允许
    7 }

    第二步,申请权限。

    1 ActivityCompat.requestPermissions(
    2     mActivity,
    3     new String[]{Manifest.permission.READ_CONTACTS},
    4     REQUEST_CODE_PERMISSION_CONTACTS);

    第三步,权限申请回调方法。

     1 @Override
     2 public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
     3     switch (requestCode) {
     4         case REQUEST_CODE_PERMISSION_CONTACTS: {
     5             if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
     6                 //用户已授权
     7             } else {
     8                 //用户拒绝权限
     9             }
    10             return;
    11         }
    12     }
    13 }

    如此三步,看上去很简单,可真要用起来可就没有那么简单了。下面就说说这里边的坑吧。

    坑一、权限申请只能在Activity或者Fragment的上下文中,不能用getApplicationContext()。

      由于我们项目在应用初始化时要获取内存的存储路径并创建一系列文件缓存,这些操作都是写在Application的onCreate()中调用不同的Util工具类进行的,所以在Android6.0以上这么写就有点不太靠谱了。目前我的解决措施是在应用程序初始化时,先判断SDK版本,只对版本号小于23的app创建缓存文件,高于23的则在进入Activity之后再初始化。

    坑二、权限申请时使用的请求码必须小于16。

      至于什么原因不太清楚,可能谷歌公司认为权限本来就不多,没必要将请求码弄得很大占用多余的内存吧。说到请求码,也就是上面代码中未定义的常量值REQUEST_CODE_PERMISSION_CONTACTS,如果你定义的这个值超过了15,运行时就会报安全异常,提示请求码必须小于16。

    目前来说这两个坑就够我忙活一天的了,看来还是经验不足啊,以后还要多多吸取经验。

  • 相关阅读:
    centos7 composer 安装使用
    linux下安装DBeaver社区版的方式
    批处理文件中使用xcopy命令复制文件到指定位置
    Civil 3d中求路线交点
    idea 启动Jfinal项目加载不出样式
    windows文件通过rsync自动同步到Centos或者Truenas
    docker中MySQL时区不对【解决方案】
    Docker容器中MySQL异常,远程无法链接排查记录
    Mac切换Java版本
    polkit pkexec 本地提权漏洞(CVE20214034)
  • 原文地址:https://www.cnblogs.com/BobGo/p/6017538.html
Copyright © 2020-2023  润新知