从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予。此方法可以简化应用安装过程,因为用户在安装或更新应用时不需要授予权限。它还让用户可以对应用的功能进行更多控制;例如,用户可以选择为相机应用提供相机访问权限,而不提供设备位置的访问权限。用户可以随时进入应用的“Settings”屏幕调用权限。
系统权限分为两类:正常权限和危险权限:
1.正常权限不会直接给用户隐私权带来风险。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。
2.危险权限会授予应用访问用户机密数据的权限。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。如果您列出了危险权限,则用户必须明确批准您的应用使用这些权限。
3.特殊权限:有许多权限其行为方式与正常权限及危险权限都不同。SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS 特别敏感,因此大多数应用不应该使用它们。如果某应用需要其中一种权限,必须在清单中声明该权限,并且发送请求用户授权的 intent。系统将向用户显示详细管理屏幕,以响应该 intent。
任何权限都可属于一个权限组,包括正常权限和应用定义的权限。但权限组仅当权限危险时才影响用户体验。
危险权限和权限组如下:
动态权限申请步骤如下:
1、AndroidManifest.xml声明权限如下:
<uses-permission android:name="android.permission.CAMERA"/>
2、判断系统版本是否是6.0及其以上:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){}
3、检测是否拥有权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {//应用没有该权限}
4、是否需要显示解释需要权限原因提示:
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {//是否应该继续显示对话框}
5、权限申请:
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 0);
完整的申请代码如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {//应用没有该权限
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {//是否应该继续显示对话框
//之前请求过拒绝了 返回true
//如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don't ask again 选项,此方法将返回 false。如果设备规范禁止应用具有该权限,此方法也会返回 false
new AlertDialog.Builder(MainActivity.this).setTitle("申请权限").setMessage("拍照需要申请相机权限,是否允许?").setPositiveButton("取消",null).setNegativeButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//点击确定的时候再次进行权限的申请
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 0);
}
}).show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 0);
}
}
}
6、权限申请回调处理:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 0:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"申请相机权限成功",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this,"申请相机权限失败",Toast.LENGTH_LONG).show();
}
break;
default:
break;
}
}
基本的申请流程就是这样,当然因为Android是开源平台,所以不同的手机厂商作了不同的处理,虽然大体一致,但是难免会存在Bug,所以推荐使用封装好的权限请求框架 AndPermission。
特殊权限的使用后续再研究。