《Android进阶之光》运行时权限Permission

Android6.0新特性,运行时权限。以打电话为例。

步骤:

1、检查权限:有就打电话;没有就请求权限(如果之前用户拒绝过,先提示为啥需要这个权限)。

2、请求权限回来后:如果成功就打电话;没成功就提示被拒绝(如果勾选了“不再询问”则提示如何手动打开权限)。

代码如下:


    private void call() {
        
        //检查权限
        if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            //没有就去申请
            if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CALL_PHONE)) {
                // 用户拒绝过这个权限了,应该提示用户,为什么需要这个权限。
                AlertDialog dialog = new AlertDialog.Builder(getContext())
                        .setMessage("解释一下,因为你要打电话,所以需要打电话权限。")
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                                //继续请求权限
                                requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, PERMISSIOINS_REQUEST_CODE_CALL);
                            }
                        }).create();
                dialog.show();
            }else {
                //请求权限,fragment中运行时权限的特殊处理、在Fragment中申请权限、不要使用ActivityCompat.requestPermissions、直接使用Fragment的requestPermissions方法、否则会回调到Activity的 onRequestPermissionsResult
                requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, PERMISSIOINS_REQUEST_CODE_CALL);
            }
        } else {
            callPhone();
        }

    }

    /**
     * 申请权限的回调
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSIOINS_REQUEST_CODE_CALL) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                callPhone();
            }
            //拒绝后,再次弹框提示申请权限 ,若勾选“不再询问”后点击拒绝,会走此逻辑(此时shouldShowRequestPermissionRationale返回false)。
            //因为已经拒绝且不在提示,需要告诉用户如何打开权限。
            else if (!ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CALL_PHONE)) {
                AlertDialog dialog = new AlertDialog.Builder(getContext())
                        .setMessage("该功能需要访问电话的权限,当前未打开权限! 打开权限的方法:设置-应用—权限。")
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                            }
                        }).create();
                dialog.show();
            } else {
                Toast.makeText(getContext(), "被拒绝了", Toast.LENGTH_SHORT).show();
            }
        }
    }

    /**
     * 打电话.
     * <p>
     * 注意:
     * android.intent.action.CALL需要在配置文件中添加拨号权限 且 点击后直接拨号
     * android.intent.action.DIAL只是调用拨号键盘,不用在文件中添加权限
     */
    private void callPhone() {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel:" + "10086"));
        startActivity(intent);
    }

效果图

1、第一次申请权限,用户拒绝了,再次申请时 提示用户为啥需要这个权限,以免用户勾选“不再询问”且拒绝。

2、点击确定后,申请权限的弹框 会有“不在询问”的勾选框

3、勾选“不再询问”后拒绝 的提示,告诉用户怎么打开权限。

比较好的文章及框架:

Android 6.0 运行时权限管理最佳实践

目前最流行的运行时权限请求框架PermissionsDispatcher、RxPermissions和easypermissions的使用和对比

发布了53 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/hfy8971613/article/details/87183603