Android6.0运行时权限问题(一)

  之前因为一直做TV开发,目前国内TV盒子系统基本都在4.4以下,所以一直很少接触新系统的特性。最近又回归到手机开发,所以也补补课,写点东西就当给自己补课了。
  Android6.0相较于之前的版本最直观的变化应该就是关于权限的管理了。6.0以前权限申请写到AndroidManifest.xml中就万事大吉,但是6.0之后对于一些高危权限,比如读取通讯录,读写sdcard分区等,不仅需要写到清单文件中,而且需要在使用之前向用户主动提出申请,否则即使在清单文件中申请了相应权限,但是依旧会报错。
  首先,我们来看一下都有哪些权限需要运行时进行申请:

//联系人
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
//外部存储(即sdcard分区 )
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

  对于同一个权限组的权限,只要申请了其中一个,你也是可以使用其他权限的,实际上Android系统对于申请权限时的描述也是针对于整个权限组的。
  当然首先在申请权限之前,我们可以先判断一下我们是否获取到了用户的授权,这里就以读写sdcard分区为例,判断代码如下:

int code = ContextCompat.checkSelfPermission(getApplicationContext(),
     Manifest.permission.READ_EXTERNAL_STORAGE);
if (code== PackageManager.PERMISSION_GRANTED){
   //表示通过授权
}

如果没有通过授权,那么我们就要来进行权限申请,申请代码如下:

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},                    
    1);

  这里的三个参数分别是Context对象,权限组(这个权限组的意思是多个权限),权限申请码(这个和startActivity中的requestCode同理)。调用这个方法之后,我们需要在Activity中的覆写onRequestPermissionsResult 方法。范例如下:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull 
       int[] grantResults) {
       super.onRequestPermissionsResult(requestCode, permissions, grantResults);
       if (requestCode==1){
            if (grantResults[0]==PackageManager.PERMISSION_GRANTED){
                //读写sdcard权限通过
            }else if (grantResults[0]!=PackageManager.PERMISSION_GRANTED){
                //读写sdcard权限没有通过
            }
        }
}

  但是如果用户已经拒绝过我们的权限申请怎么办呢?这个时候我们需要使用到另外一个api:shouldShowRequestPermissionRationale 这个API的作用是告诉我们是否应该给用户展示一个关于对权限使用的提示说明,这样我们可以在用户永久拒绝了权限申请的时候,通过这个引导用户来重新开启权限。
  所以完整的流程应该是下面这样的:
  

int code = ContextCompat.checkSelfPermission(getApplicationContext(), 
    Manifest.permission.READ_EXTERNAL_STORAGE);
if (code== PackageManager.PERMISSION_GRANTED){
   //表示通过授权
}else{          
    if(ActivityCompat.shouldShowRequestPermissionRationale(this,
        Manifest.permission.READ_EXTERNAL_STORAGE)){
        //展示提示说明
        Toast.makeText(this,"我们需要这项权限才能为您提供更好的服务",Toast.LENGTH_SHORT).show();
        ActivityCompat.requestPermissions(this, new String[]
            {Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
     }else{
        ActivityCompat.requestPermissions(this, new String[]
            {Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
      }
}        
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull 
       int[] grantResults) {
       super.onRequestPermissionsResult(requestCode, permissions, grantResults);
       if (requestCode==1){
            if (grantResults[0]==PackageManager.PERMISSION_GRANTED){
                //读写sdcard权限通过
            }else if (grantResults[0]!=PackageManager.PERMISSION_GRANTED){
                //读写sdcard权限没有通过
            }
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值