Android 6.0 动态权限申请通用的处理方式

在Android6.0之前只需在AndroidManifest.xml文件写明权限即可。但是在Android6.0之后也就是SDK>=23的时候,一些隐私权限需要动态申请,而且在用户同意授权之后App才能拥有该权限。虽然不难,但写下来代码工作量也不少,而且几乎每个应用都需要用到。所以一个简单简洁优雅的处理方式是非常重要的。

思路:

如果在每个用到权限的地方去申请,有点繁琐,所以做法是直接在每个Activity界面显示前就把该界面所需的权限全部申请允许了,再进入正常的流程。如果有权限未被允许,开发者可以在接口中自己处理,可以直接提示并退出,或者提示权限的作用后重新发起权限申请。

使用系统提供的API:
动态权限的核心工作流程:checkSelfPermission检查是否已被授予——>requestPermissions申请权限——>自动回调onRequestPermissionsResult——shouldShowRequestPermissionRationale。无论什么框架变出花来都离不开这个基本的流程。

ContextCompat.checkSelfPermission(): 检查权限是否已经授权
ActivityCompat.requestPermissions():动态申请权限,并弹出对话框。
onRequestPermissionsResult():在activity里面重写该方法该方法是权限申请之后的回调方法。shouldShowRequestPermissionRationale() :当应用首次申请权限时,如果用户点击拒绝,下次再申请权限,Android允许你提示用户,你为什么需要这个权限,更好引导用户是否授权,其中在Android原生系统中:如果应用之前请求过此权限但用户拒绝了请求,此方法将返回true;如果用户在过去拒绝了权限请求且在权限请求系统对话框中选择了 Don’t ask again 选项将返回 false;如果第一次申请权限也返回false;如果设备规范禁止应用具有该权限,此方法也会返回 false,返回false则不在显示提示对话框,返回true则会显示对话框。

下面先看下申请动态权限时的运行效果图:

1.初次进入界面时,申请所需的全部权限:

2.点击打电话按钮申请单个权限时:

3.拒绝授予权限,且勾选了不再提示:

4.拒绝权限并不再提示,告知用户该权限的作用:

5.提示用户开启权限:

点击“立即开启”跳到权限设置页面:

使用方式:

先从Activity的使用开始。

/**
 * Created by YuShuangPing on 2018/11/1.
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener, PermissionInterface {
    private int requestCode = 10000;
    private Button btn_phone;//打电话
    private Button btn_camera;//打开相机
    private PermissionHelper mPermissionHelper;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_phone = findViewById(R.id.btn_phone);
        btn_camera = findViewById(R.id.btn_camera);
        btn_phone.setOnClickListener(this);
        btn_camera.setOnClickListener(this);
        //初始化
        mPermissionHelper = new PermissionHelper(this, this);
        //发起权限申请
        mPermissionHelper.requestPermissions(new String[]{Manifest.permission.CALL_PHONE,
                Manifest.permission.CAMERA});
 
    }
 
    //点击监听
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_phone://打电话
                requestCode = 0;
                mPermissionHelper.requestPermissions(new String[]{Manifest.permission.CALL_PHONE});
 
                break;
            case R.id.btn_camera://打开相机
                requestCode = 1;
                mPermissionHelper.requestPermissions(new String[]{Manifest.permission.CAMERA});
 
                break;
        }
 
    }
 
    /**
     * 可设置请求权限请求码
     */
    @Override
    public int getPermissionsRequestCode() {
        //设置权限请求requestCode,只有不跟onRequestPermissionsResult方法中的其他请求码冲突即可。
        return requestCode;
    }
 
 
    /**
     * 请求权限成功回调
     */
    @Override
    public void requestPermissionsSuccess() {
        //权限请求用户已经全部允许
        if (requestCode == 10000) {
 
        } else if (requestCode == 0) {
            Intent intent = new Intent(Intent.ACTION_DIAL);
            Uri data = Uri.parse("tel:" + 10086);
            intent.setData(data);
            startActivity(intent);
        } else if (requestCode == 1) {
            Intent intent1 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(intent1, 0);
        }
 
    }
 
    /**
     * 请求权限失败回调
     */
    @TargetApi(Build.VERSION_CODES.M)
    @Override
    public void requestPermissionsFail() {
        //权限请求不被用户允许。可以提示并退出或者提示权限的用途并重新发起权限申请。
        if (requestCode==10000){
 
        }else if (requestCode == 0) {
            //如果拒绝授予权限,且勾选了再也不提醒
            if (!shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) {
                DialogUtil.showSelectDialog(this, "说明", "需要使用电话权限,进行电话测试", "取消", "确定", new DialogUtil.DialogClickListener() {
                    @Override
                    public void confirm() {
                        //用于在用户勾选“不再提示”并且拒绝时,再次提示用户
                        DialogUtil.showSelectDialog(MainActivity.this, "电话权限不可用", "请在-应用设置-权限中,允许APP使用电话权限来测试", "取消", "立即开启", new DialogUtil.DialogClickListener() {
                            @Override
                            public void confirm() {
                                goToAppSetting();
                            }
 
                            @Override
                            public void cancel() {
 
                            }
                        }).show();
                    }
 
                    @Override
                    public void cancel() {
 
                    }
                }).show();
            } else {
                DialogUtil.showSelectDialog(MainActivity.this, "电话权限不可用", "请在-应用设置-权限中,允许APP使用电话权限来测试", "取消", "立即开启", new DialogUtil.DialogClickListener() {
                    @Override
                    public void confirm() {
                        goToAppSetting();
                    }
 
                    @Override
                    public void cancel() {
 
                    }
                }).show();
            }
 
        }else if (requestCode==1){
            //如果拒绝授予权限,且勾选了再也不提醒
            if (!shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) {
                DialogUtil.showSelectDialog(this, "说明", "需要使用相机权限,进行相机测试", "取消", "确定", new DialogUtil.DialogClickListener() {
                    @Override
                    public void confirm() {
                        //用于在用户勾选“不再提示”并且拒绝时,再次提示用户
                        DialogUtil.showSelectDialog(MainActivity.this, "相机权限不可用", "请在-应用设置-权限中,允许APP使用相机权限来测试", "取消", "立即开启", new DialogUtil.DialogClickListener() {
                            @Override
                            public void confirm() {
                                goToAppSetting();
                            }
 
                            @Override
                            public void cancel() {
 
                            }
                        }).show();
                    }
 
                    @Override
                    public void cancel() {
 
                    }
                }).show();
            } else {
                DialogUtil.showSelectDialog(MainActivity.this, "相机权限不可用", "请在-应用设置-权限中,允许APP使用相机权限来测试", "取消", "立即开启", new DialogUtil.DialogClickListener() {
                    @Override
                    public void confirm() {
                        goToAppSetting();
                    }
 
                    @Override
                    public void cancel() {
 
                    }
                }).show();
            }
        }
 
 
    }
 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (mPermissionHelper.requestPermissionsResult(requestCode, permissions, grantResults)) {
            //权限请求结果,并已经处理了该回调
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
 
    /**
     * 打开Setting
     */
    private void goToAppSetting() {
        Intent intent = new Intent();
        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", getPackageName(), null);
        intent.setData(uri);
        startActivityForResult(intent, 123);
    }
 
 
}

2.Dialog工具类:

/**
 * Created by YuShuangPing on 2018/11/5.
 */
public class DialogUtil {
    /**
     * 创建一个选择对话框
     *
     * @param context
     * @param pContent            提示消息
     * @param dialogClickListener 点击监听
     * @return
     */
    public static Dialog showSelectDialog(Context context, String title, String pContent, String pLeftBtnStr,
                                          String pRightBtnStr,
                                          final DialogClickListener dialogClickListener) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        AlertDialog dialog = builder.setTitle(title)
                .setMessage(pContent)
                .setPositiveButton(pRightBtnStr, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialogClickListener.confirm();
                        dialog.dismiss();
                    }
                })
                .setNegativeButton(pLeftBtnStr, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialogClickListener.cancel();
                        dialog.dismiss();
//                        return;
                    }
                })
                .create();
        return dialog;
    }
 
 
    public interface DialogClickListener {
 
        public abstract void confirm();
 
        public abstract void cancel();
 
    }
}

权限的接口类:

/**
 * 权限请求接口
 * Created by YuShuangPing on 2018/11/1.
 */
public interface PermissionInterface {
 
    /**
     * 可得到请求权限请求码
     */
    int getPermissionsRequestCode();
 
    /**
     * 请求权限成功回调
     */
    void requestPermissionsSuccess();
 
    /**
     * 请求权限失败回调
     */
    void requestPermissionsFail();
 
}
权限的帮助类:

/**
 * 动态权限帮助类
 * Created by YuShuangPing on 2018/11/1.
 */
public class PermissionHelper {
    private Activity mActivity;
    private PermissionInterface mPermissionInterface;
 
    public PermissionHelper(@NonNull Activity activity, @NonNull PermissionInterface permissionInterface) {
        mActivity = activity;
        mPermissionInterface = permissionInterface;
    }
 
    /**
     * 开始请求权限。
     * 方法内部已经对Android M 或以上版本进行了判断,外部使用不再需要重复判断。
     * 如果设备还不是M或以上版本,则也会回调到requestPermissionsSuccess方法。
     */
    public void requestPermissions(String[] permissions) {
        String[] deniedPermissions = PermissionUtil.getDeniedPermissions(mActivity, permissions);
        if (deniedPermissions != null && deniedPermissions.length > 0) {
            PermissionUtil.requestPermissions(mActivity, deniedPermissions, mPermissionInterface.getPermissionsRequestCode());
        } else {
            mPermissionInterface.requestPermissionsSuccess();
        }
    }
 
    /**
     * 在Activity中的onRequestPermissionsResult中调用
     * @param requestCode
     * @param permissions
     * @param grantResults
     * @return true 代表对该requestCode感兴趣,并已经处理掉了。false 对该requestCode不感兴趣,不处理。
     */
    public boolean requestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == mPermissionInterface.getPermissionsRequestCode()) {
            boolean isAllGranted = true;//是否全部权限已授权
            for(int result : grantResults){
                if(result == PackageManager.PERMISSION_DENIED){
                    isAllGranted = false;
                    break;
                }
            }
            if(isAllGranted){
                //已全部授权
                mPermissionInterface.requestPermissionsSuccess();
            }else{
                //权限有缺失
                mPermissionInterface.requestPermissionsFail();
            }
            return true;
        }
        return false;
    }
    }

权限的工具类:

/**
 * 动态权限工具类
 * Created by YuShuangPing on 2018/11/1.
 */
public class PermissionUtil {
 
    /**
     * 弹出对话框请求权限
     * @param activity
     * @param permissions
     * @param requestCode
     */
    public static void requestPermissions(Activity activity, String[] permissions, int requestCode) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            activity.requestPermissions(permissions, requestCode);
        }
    }
 
    /**
     * 返回缺失的权限
     * @param context
     * @param permissions
     * @return 返回缺少的权限,null 意味着没有缺少权限
     */
    public static String[] getDeniedPermissions(Context context, String[] permissions) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ArrayList<String> deniedPermissionList = new ArrayList<>();
            for (String permission : permissions) {
                if (context.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                    deniedPermissionList.add(permission);
                }
            }
            int size = deniedPermissionList.size();
            if (size > 0) {
                return deniedPermissionList.toArray(new String[deniedPermissionList.size()]);
            }
        }
        return null;
    }
 
}

在需要权限的界面进行调用就可以了,如果想看具体的效果可以下载demo,导入AndroidStudio

本文为转载文章,如有侵权,立马删
版权声明:本文为 yushuangping 博主原创文章,遵循 CC 4.0 BY-SA 版权协议,此为转载
原文链接:https://blog.csdn.net/yushuangping/article/details/83758957

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值