0. Thanks To
1. 概述
在Android6.0及其以上,对权限进行了进一步限制。一些危险级别的权限,需要代码中去向用户申请才能使用,不然,会报异常:java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider
,那么问题来了,是不是所有以前发布的app都会出现问题呢?答案是不会,只有那些targetSdkVersion设置为23和23以上的应用才会出现异常,在使用危险权限的时候系统必须要获得用户的同意才能使用,要不然应用就会崩溃。
2. 权限的分类
- 危险权限
Permission Group | Permissions | Desc描述 |
---|---|---|
android.permission-group.CALENDAR | android.permission.READ_CALENDAR | 允许程序读取用户的日程信息 |
android.permission.WRITE_CALENDAR | 写入日程,但不可读取 | |
android.permission-group.CAMERA | android.permission.CAMERA | 允许访问摄像头进行拍照 |
android.permission-group.CONTACTS | android.permission.READ_CONTACTS | 允许应用访问联系人通讯录信息 |
android.permission.WRITE_CONTACTS | 写入联系人,但不可读取 | |
android.permission-group.LOCATION | android.permission.ACCESS_FINE_LOCATION | 通过GPS芯片接收卫星的定位信息,定位精度达10米以内 |
android.permission.ACCESS_COARSE_LOCATION | 通过WiFi或移动基站的方式获取用户错略的经纬度信息,定位精度大概误差在30~1500米 | |
android.permission-group.MICROPHONE | android.permission.RECORD_AUDIO | 录制声音通过手机或耳机的麦克 |
android.permission-group.PHONE | android.permission.READ_PHONE_STATE | 访问电话状态 |
android.permission.CALL_PHONE | 允许程序从非系统拨号器里输入电话号码 | |
android.permission.READ_CALL_LOG | '' | |
android.permission.WRITE_CALL_LOG | '' | |
com.android.voicemail.permission.ADD_VOICEMAIL | '' | |
android.permission.USE_SIP | 允许程序使用SIP视频服务 | |
android.permission.PROCESS_OUTGOING_CALLS | 允许程序监视,修改或放弃播出电话 | |
android.permission-group.SENSORS | android.permission.BODY_SENSORS | '' |
android.permission-group.SMS | android.permission.SEND_SMS | 允许发送短信 |
android.permission.RECEIVE_SMS | 允许接受短信 | |
android.permission.READ_SMS | 允许读取短信 | |
android.permission.RECEIVE_WAP_PUSH | 接收WAP PUSH信息 | |
android.permission.RECEIVE_MMS | 接收彩信 | |
android.permission.READ_CELL_BROADCASTS | '' | |
android.permission-group.STORAGE | android.permission.READ_EXTERNAL_STORAGE | 允许访问存储设备 |
android.permission.WRITE_EXTERNAL_STORAGE | 允许写入存储设备 |
3. 权限申请示例
检查权限,然后判断是否已经允许了,未允许就去申请:
String[] permissions = new String[] {
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
int result = ContextCompat.checkSelfPermission(this, permissions[0]);
switch (result) {
case PackageManager.PERMISSION_DENIED:
ActivityCompat.requestPermissions(this, permissions, 0x02);
break;
case PackageManager.PERMISSION_GRANTED:
//do some things
break;
}
复制代码
在 onRequestPermissionsResult 里面接收结果,需要遍历出当前 String[] permissions 返回的申请列表中的某一个权限,然后取出结果。do some things 应该包装成一个方法,得到权限后,就去做某件事情。ActivityCompat.shouldShowRequestPermissionRationale 返回值是,系统是否有显示权限获取的dialog,如果是false,就是什么都没有弹出来,则我们需要主动去引导用户去开启权限,例如打开设置页面。
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 0x02:
for (int i = 0; i < permissions.length; i++) {
String permission = permissions[i];
if (permission.equalsIgnoreCase(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
switch (grantResults[i]) {
case PackageManager.PERMISSION_DENIED:
boolean shouldShowTips = ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[0]);
if (!shouldShowTips)
Toast.makeText(this,"请到设置里面开启权限!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this,"您已经禁止了权限了", Toast.LENGTH_SHORT).show();
break;
case PackageManager.PERMISSION_GRANTED:
//do some things
break;
}
}
}
break;
}
}
复制代码