说说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。

 

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

posted on 2016-10-31 22:03  白少木丿  阅读(551)  评论(0编辑  收藏  举报

导航