该系列的文章只是本人的一些个人理解、随笔、总结,也深怕误人子弟,如果理解有错的地方还希望看到的朋友指正,不胜感激!!!
从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予:
如果设备运行的是 Android 5.1 或更低版本,或者应用的目标 SDK 为 22 或更低:如果您在清单中列出了危险权限,则用户必须在安装应用时授予此权限;如果他们不授予此权限,系统根本不会安装应用。
如果设备运行的是 Android 6.0 或更高版本,或者应用的目标 SDK 为 23 或更高:应用必须在清单中列出权限,并且它必须在运行时请求其需要的每项危险权限。用户可以授予或拒绝每项权限,且即使用户拒绝权限请求,应用仍可以继续运行有限的功能。
以下是危险权限及所在的权限组:
检测你的应用是否已经获取了某个危险权限(这里以读取手机联系人为例):
int checkSelfPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS);
如果checkSelfPermission等于PackageManager.PERMISSION_GRANTED则说明应用已获取该权限.需要注意的是:当你的清单文件中申明了某组权限中的几个权限时,只要用户同意了其中的一个权限,那么其他的权限也被授予.
如何申请危险权限(还是以读取联系人为例),以下为代码:
//判断应用是否已经获取了读取联系人的权限
int checkSelfPermission = ContextCompat.checkSelfPermission(this, Manifest
.permission.READ_CONTACTS);
//应用尚未获取该权限
if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) {
//shouldShowRequestPermissionRationale()函数会返回一个boolen值,当同一设备第一次安装
//你的应用且第一次申请该权限时才会返回false,如果用户拒绝了这次请求,
//那么用户再次申请该权限且未勾选"拒绝后不再提示"时则会返回true,我们可以在这里向用户解释这个权限的必要性,我这里只是
//做了一个简单的弹框.当然,你也可以什么都不做,直接请求权限也行,看需求来.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest
.permission.READ_CONTACTS)) {
//
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setCancelable(false)
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
ActivityCompat.requestPermissions(MainActivity.this, new
String[]{Manifest.permission
.READ_CONTACTS},
110);
}
})
.setMessage("允许应用读取联系人信息?")
.setTitle("提示")
.create();
alertDialog.show();
} else {
//申请该权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission
.READ_CONTACTS},
110);
}
} else {
Toast.makeText(MainActivity.this, "已获取该权限", Toast.LENGTH_SHORT).show();
//TODO
}
处理权限申请结果,当前Activity重写以下函数处理:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
switch (requestCode) {
case 110: {
// 如果取消了申请,则grantResults数组为空,这里的grantResults数组长度对应requestPermissions()中请求的权限数组长度
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "获取到权限", Toast.LENGTH_SHORT).show();
//TODO
} else {
Toast.makeText(MainActivity.this, "未获取权限", Toast.LENGTH_SHORT).show();
//TODO
}
} else {
Toast.makeText(MainActivity.this, "取消申请权限", Toast.LENGTH_SHORT).show();
//TODO
}
return;
}
}
}
当用户第一次拒绝了权限申请,那么接下来的申请,弹框中会多出一个"拒绝后不再提示"的选项(首次申请没有),如果用户勾选了"拒绝后不再提示",这种情况下,无论应用在什么时候使用 requestPermissions() 再次要求该权限,系统都会立即拒绝此请求。系统会调用您的 onRequestPermissionsResult() 回调方法,并传递 PERMISSION_DENIED.那怎么监听用户勾选了"拒绝后不再提示"呢?后续研究...