项目开发过程中,碰到6.0系统的手机。然后看了6.0运行时权限的相关资料,总结如下:
运行时权限相关API
1、常量
PackageManager.PERMISSION_DENIED:该权限是被拒绝的。
PackageManager.PERMISSION_GRANTED:该权限是被授权的。
2、方法
ContextCompat.checkSelfPermission(): 检查权限
解释:检查某一个权限的当前状态,你应该在请求某个权限时检查这个权限是否已经被用户授权。该方法有一个参数是权限名称,有一个int的返回值,用这个值与上面的常量进行比较可判断检查的权限当前的状态。例子:
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// 没有权限,申请权限。
}else{
// 有权限,去做该做的事。
}
ActivityCompat.requestPermissions() : 申请权限
参数:
int requestCode :会在回调onRequestPermissionsResult()
时返回,用来判断是哪个授权申请的回调。
String[] permissions:权限数组,你需要申请的的权限的数组。
解释:由于该方法是异步的,所以无返回值,当用户处理完授权操作时,会回调Activity或者Fragment的onRequestPermissionsResult()
方法。例子:
ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.READ_CONTACTS}, 1);
onRequestPermissionsResult() :处理权限结果回调
参数:
int requestCode :调用requestPermissions()
时参数
String[] permissions :权限数组
int[] grantResults :授权结果数组
例子:
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 权限被用户同意
} else {
// 权限被用户拒绝了
}
return;
}
}
}
shouldShowRequestPermissionRationale() :是否应该显示请求权限的说明
解释:只有在用户在上一次已经拒绝过你的这个权限申请,也就是说,用户已经拒绝一次了,你又弹个授权框,你需要给用户一个解释,为什么要授权,则使用该方法。
private void requestPermission(Activity context, String permission) {
if (Build.VERSION.SDK_INT >= 23) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {//没有授权
if (ActivityCompat.shouldShowRequestPermissionRationale(context, permission)) {
showMessageDialog(context);//用户拒绝过这个权限了,应该提示用户,为什么需要这个权限
} else {
ActivityCompat.requestPermissions(activity, new String[]{requestPermission}, 1);//申请授权
}
} else {
//已经授权了,直接做事
}
} else {//小于23
//直接做该做的事
}
}
private void showMessageDialog(Activity context) {
//自定义权限弹出框
//点击确定,执行下面代码
ActivityCompat.requestPermissions(activity, new String[]{requestPermission}, 1);
}
.........
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {//已授权
//直接操作
} else {//未授权
// 打开本应用信息界面,由用户自己手动开启这个权限
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);//this.getPackageName()
intent.setData(uri);
startActivity(intent);
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
最后,再补充点知识:
新的权限策略讲权限分为两类,第一类是不涉及用户隐私的,只需要在Manifest中声明即可,比如网络、蓝牙、NFC等;第二类是涉及到用户隐私信息的,需要用户授权后才可使用,比如SD卡读写、联系人、短信读写等。我们在项目中,只处理危险权限,所有危险的Android系统权限属于权限组,如果APP运行在Android 6.0 (API level 23)
或者更高级别的设备中,而且targetSdkVersion>=23
时,系统将会自动采用动态权限管理策略,如果你在涉及到特殊权限操作时没有做动态权限的申请将会导致App崩溃,因此你需要注意:
1 .此类权限也必须在Manifest中申明,否则申请时不提示用户,直接回调开发者权限被拒绝。
2.同一个权限组的任何一个权限被授权了,这个权限组的其他权限也自动被授权。
需要注意的危险权限组:
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