自Android6.0后有了动态权限管理,涉及到用户隐私的危险权限需要用户手动确认之后才可以使用,这里主要总结了原生,EasyPermissions,RxPermissions以及PermissionsDispatcher四种方式。
1.原生请求。
权限请求:
String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
public void original() {
ArrayList<String> strings = new ArrayList<>();
for (String item : permissions) {//循环对所有权限进行检查
if (ContextCompat.checkSelfPermission(this, item) == PackageManager.PERMISSION_GRANTED) {//权限允许
} else {
strings.add(item);
}
}
if (strings.size() > 0) {//对没有允许的权限进行请求
ActivityCompat.requestPermissions(this, strings.toArray(new String[strings.size()]), REQUEST_PERMISSION);
}
}
请求结果返回:
@Override
/*permissions和grantResults中子项是一一对应的*/
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_PERMISSION://原生权限检测返回
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//这个只是代表了在这一部分同时请求的权限至少有一个被允许了
ArrayList<Object> others = new ArrayList<>();
for (int i = 0; i < grantResults.length; i++) {
int item = grantResults[i];
if (item == PackageManager.PERMISSION_GRANTED) {//条件允许
} else {//此处是对每一项未被允许的权限进行说明
others.add(permissions[i]);
Toast.makeText(this, "您已拒绝提供" + (permissions[i].equals(Manifest.permission.CAMERA) ? "相机权限" : "读写权限"), Toast.LENGTH_SHORT).show();
}
}
if (others.size() > 0) {//如果存在未被允许的权限就要进行另外的操作处理
}
} else {
Toast.makeText(this, "您已拒绝提供相关权限,如需继续使用请在设置中打开", Toast.LENGTH_SHORT).show();
}
break;
}
}
权限请求:
String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
public void EasyPermissions() {
if (EasyPermissions.hasPermissions(this, permissions)) {//有全部的权限,做对应的操作
Toast.makeText(this, "该应用已拥有所有权限", Toast.LENGTH_SHORT).show();
} else {
PermissionRequest request = new PermissionRequest.Builder(this, REQUEST_PERMISSION_EASY, permissions)
.setRationale("该App正常使用需要用到的权限")
.setNegativeButtonText("不可以哟")
.setPositiveButtonText("允许")
// .setTheme(R.style.myPermissionStyle)
.build();
EasyPermissions.requestPermissions(request);
}
}
请求结果返回:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);//将请求结果交由 EasyPermissions处理
}
@Override
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
//权限申请成功
if (perms != null && perms.size() > 0) {
StringBuffer stringBuffer = new StringBuffer();
for (String item : perms) {
stringBuffer.append(item).append(",");
}
Toast.makeText(this, "该应用已允许权限:" + stringBuffer.toString().trim(), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
//权限申请失败
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this).build().show();
}
}
权限请求:
要给对应使用权限的activity或fragment添加注解@RuntimePermissions 来进行注册
@NeedsPermission({Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE})
public void disPer() {
//TODO 此处写上需要用到权限的操作
//下面这个方法是用来调取未被允许的权限的,如果权限都已经被允许了,这个方法会引起死循环
MainActivityPermissionsDispatcher.disPerWithPermissionCheck(this);
}
请求结果返回:
@Override
/*permissions和grantResults中子项是一一对应的*/
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}
//下面两个方法中的请求要和申请时的一一对应 @OnPermissionDenied({Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE})
public void onCameraDenied() {
Toast.makeText(this, "失败", Toast.LENGTH_SHORT).show();
}
@OnNeverAskAgain({Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE})
public void onCameraNeverAskAgain() {
Toast.makeText(this, "并不再询问", Toast.LENGTH_SHORT).show();
}
权限请求:
使用方式分为两种:
a.单独调用:
RxPermissions rxPermissions = new RxPermissions(this);
将所有的权限请求结果合并到一起处理
rxPermissions.request(permissions).subscribe(boo->{
if (boo) {//授权
Toast.makeText(this, "该应用已允许权限", Toast.LENGTH_SHORT).show();
} else {//未授权
Toast.makeText(this, "该应用已拒绝权限", Toast.LENGTH_SHORT).show();
}
});
//对每一个权限请求结果进行处理
rxPermissions
.requestEach(permissions)
.subscribe(permission -> {
if (permission.granted) {//授权
Toast.makeText(this, "该应用已允许权限:" + permission.name, Toast.LENGTH_SHORT).show();
} else {//未授权
Toast.makeText(this, "该应用已拒绝权限:" + permission.name, Toast.LENGTH_SHORT).show();
}
});
b.和RxBinding配合使用:
//权限结果合并处理
RxView.clicks(findViewById(R.id.enableCamera))
.compose(rxPermissions.ensure(Manifest.permission.CAMERA))
.subscribe(granted -> {
// R.id.enableCamera has been clicked
});
//权限结果单独处理
RxView.clicks(mLlScan)
.compose(rxPermissions.ensureEach(Manifest.permission.CAMERA))
.subscribe(permission -> {
if (permission.granted){
}else if (permission.shouldShowRequestPermissionRationale){
}else {
}
});
关于Android11以上部分型号手机强制存储权限申请:
public static boolean isManager(Context context) {
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
//判断当前手机系统是否是Android11
if (Environment.isExternalStorageManager()) {
return true;
}else {
AlertDialog alertDialog;
AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.DialogStyle);
builder.setPositiveButton("确认", null);
builder.setTitle("缺少必要权限");
builder.setMessage("Android 11 需要授予所有文件的管理权限");
builder.setCancelable(false);
alertDialog = builder.create();
alertDialog.show();
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
alertDialog.dismiss();//去获取文件管理
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse("package:" + context.getPackageName()));
((Activity)context).startActivityForResult(intent, 0x99);
});
return false;
}
} else {
return true;
}
}