授权:
什么是权限:
权限管理是所有后台系统的都会涉及的一个重要组成部分,主要目的是对不同的人访问资源进行权限的控制,避免因权限控制缺失或操作不当引发的风险问题,如操作错误,隐私数据泄露等问题。权限归为两类,一类是普通权限,一类的危险权限,危险权限则表示那些可能会触及到用户安全隐私或者对设备安全造成影响的权限:
危险权限:
CONTACTS(联系人)
LOCATION(位置)
MICROPHONE(麦克风)
PHONE(手机)
SENSORS(传感器)
SMS(短信)
STORAGE(存储卡)
CALENDAR(日历)
CAMERA(相机)
授权原理:(以相机为列)
1.首先判断是否有相应的权限(清单文件)
有:直接调用相应的代码(打开相机)
没有:请求授权
用户同意:在回调里面直接调用相应的代码(打开相机)
用户拒绝;{
1. 如果在此点击拒绝:不用直接请求授权,可以弹出个AlertDialong 向用户解释为什么需要这个权限。如果用户看明白。点击同意:请求授权再次弹出系统授权对话框。
2.如果用户拒绝了并且点击了不在提示:用户再此点击按钮请求授权,系统会直接回调授权失败,不会弹出任何对话框。
3.如果用户再此获取此权限 ,就要进行判断:并跳到相应的应用授权界面。
}
注意:授权对话款的不在提示,只要在第一次拒绝授权后,第二次请求授权才会出现。
AlerTDialong 对话框
对话框.PNG跳转到应用的设置页面
设置.PNG在我们使用授权是可以直接使用工具类。来判断获取权限。
使用工具类:
定义一个必须授权的,一可选的权限。
使用工具类的方法传入四个参数 ,一个是当前的content, 接口回调,必须授权的数组,可选权限的数组。
在shouldShowRationale中调用AlerTDialong 对话框 的方法 在shouldShowPermissionSetting中调用跳转到应用的设置页面的方法
下图中第一个testButton 是自己定义的,textButton 是使用工具类的
/**
* 1. 第一次点击按钮:判断是否有相应的权限,
* 有:直接调用相应代码(打开相机)
* 没有:请求授权
* 如果用户同意:在回调里面直接调用相应代码(打开相机)
* 如果用户拒绝:
* 如果用户再次点击按钮:不要直接请求授权
* 弹出一个自己写的pop or dialog 向用户解释为什么需要这个权限。
* 如果用户看明白了,点击了同意:
* 请求授权再次弹出系统授权对话框
* 如果用户同意:在回调里面直接调用相应代码(打开相机)
* 如果用户拒绝了并且点击了不在提示:
* 用户在此点击按钮请求授权:系统会直接回调授权失败,不会弹出任何授权对话框
* <p>
* <p>
* 如果用户仍然掉了决绝:
* <p>
* <p>
* <p>
* <p>
* 注意:授权对话框的不在提示,只要在第一次拒绝授权后,第二次请求授权时才会出现
*/
public class TestPermissionActivity extends BaseActivity {
private Button testButton;
private static final String allNeedPermissions[] = new String[]{Manifest.permission.CAMERA
,Manifest.permission.READ_PHONE_NUMBERS,Manifest.permission.ACCESS_FINE_LOCATION};
private static String optionalPermissions [] = new String[]{Manifest.permission.BODY_SENSORS}; // 这个权限是可选的
private ArrayList<String> unGrantedPermissions = new ArrayList<>();
private ArrayList<String> needToSettingPermissions = new ArrayList<>(); // 未授权那一部分那种,勾选了不再提示的那一部分
private Button textButton;
@Override
protected int getLayoutId() {
return R.layout.activity_test_permission;
}
@Override
protected void initView() {
testButton = findViewById(R.id.btn);
textButton = findViewById(R.id.btn1);
testButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unGrantedPermissions.clear();
needToSettingPermissions.clear();
if (isAllGranted(allNeedPermissions)){
showToast("有权限,可以拍照!");
}else {
boolean isShouldShowDialog = isShouldShowPermissionRationale(unGrantedPermissions);
// 第一次调用这个方法(还没有请求授权),返回 false.
// 第一次以后再次调用这个(之前发生过请求授权,被用户拒绝了,但是没有勾选不再提示,如果勾选了,return false),return true. 意思就是告诉你,需要向用户解释为什么需要这个权限
Logger.d("isShouldShowDialog =%s",isShouldShowDialog);
if (isShouldShowDialog){//需要显示解释对话框
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.setMessage("上传头像需要相机权限,否则没法实现该功能").setNegativeButton("拒绝", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Logger.d("用户看了解释对话框,仍然拒绝");
}
}).setPositiveButton("同意", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Logger.d("用户看了解释对话框,同意授权");
ActivityCompat.requestPermissions(TestPermissionActivity.this, unGrantedPermissions.toArray(new String[unGrantedPermissions.size()]),100);
}
});
builder.show();
}else {
Logger.d("不需要解释对话框,直接请求授权");
ActivityCompat.requestPermissions(TestPermissionActivity.this, unGrantedPermissions.toArray(new String[unGrantedPermissions.size()]),100);
}
}
}
});
//使用了工具类
textButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new MkPermissionManager(TestPermissionActivity.this).checkPermission(TestPermissionActivity.this, new MkPermissionManager.OnPermissionCallBack() {
@Override
public void onAllMustAccept() {
showToast("所有必须权限都接受了,可以进行下一步操作");
}
@Override
public void shouldShowRationale(MkPermissionManager.PermissionCall call,String unGrantedPermissions []) {
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.setMessage("做什么,需要权限")
.setNegativeButton("决绝", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
for(int i = 0; i < unGrantedPermissions.length;i++){
for(int j = 0; j < allNeedPermissions.length; j++){
if(unGrantedPermissions[i] == allNeedPermissions[j]){
showToast("权限不足");
return;
}
}
}
showToast("所有必须权限都接受了,可以进行下一步操作");
}
}).setPositiveButton("同意", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
call.requestPermission(); // 重新请求权限
}
}).show();
}
@Override
public void shouldShowPermissionSetting() {
showSettingDialog(); // 给用解释,需要到设置页面去手动打开权限
}
@Override
public void onDenied() {
showToast("权限不足");
}
},allNeedPermissions,optionalPermissions);
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
/* if (requestCode==100){
for (int i = 0; i < grantResults.length; i++) {
Logger.d("%s==%s",permissions[i],grantResults[0]);
}
}*/
if (requestCode == 100) {
//创建一个集合 用来存储权限
ArrayList<String> deniedList = new ArrayList<>();
for(int i = 0; i < grantResults.length;i++){
//如果权限被拒绝 PackageManager.PERMISSION_DENIED: 表示拒绝
if(grantResults[i] == PackageManager.PERMISSION_DENIED){
//添加到集合中
deniedList.add(permissions[i]);
}
}
if(deniedList.size() == 0){// 如果全部授权 就吐司
showToast("全部授权");
}else{
//for 循环
for(String permission : deniedList){
//显示权限的理由为false 就 是没理由 就是 要添加权限 跳转到应用信息
if(!ActivityCompat.shouldShowRequestPermissionRationale(TestPermissionActivity.this, permission)){
showSettingDialog();
return;
}
}
showToast("权限不足");
}
}
}
//显示设置对话框
public void showSettingDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("上传头像需要相机权限,否则没法实现,点击同意按钮进入设置页面打开权限,否则点击拒绝").setNegativeButton("拒绝", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
showToast("权限不足");
}
}).setPositiveButton("同意", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Logger.d("用户同意到设置页面打开权限");
toSelfSetting(TestPermissionActivity.this);
}
});
builder.show();
}
//使用数组循环判断是否有这个权限
public boolean isAllGranted(String[] all) {
for (int i = 0; i < all.length; i++) {
if (ActivityCompat.checkSelfPermission(this, all[i]) != PackageManager.PERMISSION_GRANTED) { // 没有这个权限
unGrantedPermissions.add(all[i]);
}
}
if (unGrantedPermissions.size() > 0) {
return false;
}
return true;
}
//创建显示权限的理由
public boolean isShouldShowPermissionRationale(ArrayList<String> permissions) {
for (String permission : permissions) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(TestPermissionActivity.this, permission)) {
needToSettingPermissions.add(permission);
}
}
if(needToSettingPermissions.size() > 0){ // 有点了不在询问的权限
if(needToSettingPermissions.size() == permissions.size()){ // 所有未授权的全部点了不在询问
return false;
}
return true; // 只有有一部分需要显示的,,那么还是显示一下
}
return true; // 所有未授权的权限中,都没有点击不在询问。所以也需要
}
//进入设置页面
public static void toSelfSetting(Context context) {
Intent mIntent = new Intent();
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= 9) {
mIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
mIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
} else if (Build.VERSION.SDK_INT <= 8) {
mIntent.setAction(Intent.ACTION_VIEW);
mIntent.setClassName("com.android.settings", "com.android.setting.InstalledAppDetails");
mIntent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName());
}
context.startActivity(mIntent);
}
}
工具类:
/*
* ActivityCompat.shouldShowRequestPermissionRationale 它返回一个boolean 类型,但是分两种情况:
*
* 1. 如果用户之前决绝过授权,如果都没有点击不在询问的checkbox ,那么 return true,只要有一个点击了不在询问的checkbox return false,
* 2. 如果是在第一次请求权限之前,调用这个方法。return false; 因为用户都没有拒绝过,所有不用去显示解释dialog
*
*
**/
public class MkPermissionManager {
private RxPermissions rxPermissions;
public MkPermissionManager(FragmentActivity fragmentActivity) {
rxPermissions = new RxPermissions(fragmentActivity);
}
public MkPermissionManager(Fragment fragment) {
rxPermissions = new RxPermissions(fragment);
}
@SuppressLint("CheckResult")
public void checkPermission(final Activity activity, final OnPermissionCallBack callBack, final String [] must,String [] optional){
String all [] = concat(must, optional);
final String [] unGrantedArr = getUnGrantedPermissions(all);
if(unGrantedArr != null && unGrantedArr.length > 0){
rxPermissions.shouldShowRequestPermissionRationale(activity,unGrantedArr).subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
if(aBoolean){ // 只有用户之前拒绝过。并且所有权限都决绝时都没有点击 不在询问得checkbox,才会需要显示解释对话框
callBack.shouldShowRationale(new PermissionCall() {
@Override
public void requestPermission() {
rxPermissions.request(unGrantedArr).subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
if(aBoolean){
callBack.onAllMustAccept();
}else{
if(verifyPermissions(must)){
callBack.onAllMustAccept();
}else{
callBack.onDenied();
}
}
}
});
}
},unGrantedArr);
}else{
rxPermissions.request(unGrantedArr).subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
if(!aBoolean){
if(verifyPermissions(must)){
callBack.onAllMustAccept();
}else{
rxPermissions.shouldShowRequestPermissionRationale(activity, unGrantedArr).subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
if(!aBoolean){
callBack.shouldShowPermissionSetting();
}else{
callBack.onDenied();
}
}
});
}
}else{
callBack.onAllMustAccept();
}
}
});
}
}
});
}else{
callBack.onAllMustAccept();
}
}
private String [] concat(String [] must,String optional []){
ArrayList<String> arrayList = new ArrayList<>();
if(must != null){
arrayList.addAll( Arrays.asList(must));
}
if(optional != null){
arrayList.addAll( Arrays.asList(optional));
}
return arrayList.toArray(new String[0]);
}
private boolean verifyPermissions(String ...permissions){
if (permissions.length < 1) {
return true;
}
// Verify that each required permission has been granted, otherwise return false.
for (String per : permissions) {
if(!rxPermissions.isGranted(per)){
return false;
}
}
return true;
}
/**
* 获取所有权限中,未授权的
* @param permissions
* @return
*/
private String [] getUnGrantedPermissions(String ...permissions){
ArrayList<String> list = new ArrayList<>();
for(String permission : permissions){
if(!rxPermissions.isGranted(permission)){
list.add(permission);
}
}
if(list.size() > 0){
return list.toArray(new String[0]);
}
return null;
}
public interface OnPermissionCallBack{
// 所有必须授权的权限都授权了,
void onAllMustAccept();
// 需要显示一个解释说明的对话框,如果用户点击了同意就调用call.requestPermission 方法,如果用户拒绝,那么你需要判断一下拒绝权限里面是否包含不要权限,如果不包含,即使拒绝了,也可以继续下一步
void shouldShowRationale(PermissionCall call, String unGrantedPermissions[]);
// 当用户在授权dialog 选中了不在询问得checkbox 时,你需要引导用户去权限设置页面手动开启权限
void shouldShowPermissionSetting();
// 所有必须授权的权限只有有一个没有授权都会回掉这个。
void onDenied();
}
public interface PermissionCall{
//当显示 解释对话框时,用户点击 "确认" 或者 "同意授权时" 按钮时,调用该方法让该工具类去请求授权
void requestPermission();
}
}
网友评论