Android6.0 申请权限比较优雅的处理方法

android6.0以后权限的申请改成了动态申请,如果你的targetSdkVersion 大于23且手机系统是6.0以上的就会变成动态申请.为了项目的需求我自己整理了一套权限申请的方法.先上几张图片.
1.这是我第一次运行项目弹出权限请求的界面,我都选择了不允许,然后会通过Snackbar友好的提醒用户需要允许权限

2.当我第二次在点击拍照时,就会先弹出一个Snackbar告诉用户,我需要一些权限,这次我还是决绝而且还点击了不再提醒.这样用户下次在点击拍照时就无法弹出申请权限的界面了,这里我就通过Snackbar提醒用户是否要去设置界面开启权限

3.这是我选择了不再询问以后再次点击拍照的时候,这时就会直接弹出Snackbar提醒用户是否要去设置界面开启权限

通过上面的图片效果,应该可以看出这套权限请求的过程了,下面我就贴一下代码.
1.我把权限请求封装到了一个工具类中,代码如下
`public class PermissionUtil {

/**
 * 检测权限
 * @param activity
 * @param view //随便一个view 来用显示snackbar
 * @param permissions  //请求的权限组
 * @param requestCode  //请求码
 */
public  static void checkPermission(final Activity activity,View view, final String[] permissions, final int requestCode,permissionInterface permissionInterface) {
    //小于23 就什么都不做
    if (Build.VERSION.SDK_INT < 23) {
        return;
    }
    List<String> deniedPermissions = findDeniedPermissions(activity, permissions);
    if (deniedPermissions!=null&&deniedPermissions.size()>0) {
        //大于0,表示有权限没申请
        PermissionUtil.requestContactsPermissions(activity, view,  deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
    } else {
        //拥有权限
        permissionInterface.success();

    }
}

/**
 * 请求权限
 */
public static void requestContactsPermissions(final Activity activity,View view, final String[] permissions, final int requestCode) {
    //默认是false,但是只要请求过一次权限就会为true,除非点了不再询问才会重新变为false
    if (shouldShowPermissions(activity,permissions)) {

        Snackbar.make(view, "需要一些权限",
                Snackbar.LENGTH_INDEFINITE)
                .setAction("确定", new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        ActivityCompat
                                .requestPermissions(activity, permissions,
                                        requestCode);
                    }
                })
                .show();
    } else {

        // 无需向用户界面提示,直接请求权限,如果用户点了不再询问,即使调用请求权限也不会出现请求权限的对话框
        ActivityCompat.requestPermissions(activity,
                permissions,
                requestCode);
    }
}

/**
 * 判断请求权限是否成功
 * @param grantResults
 * @return
 */
public static boolean verifyPermissions(int[] grantResults) {
    // At least one result must be checked.
    if(grantResults.length < 1){
        return false;
    }

    // Verify that each required permission has been granted, otherwise return false.
    for (int result : grantResults) {
        if (result != PackageManager.PERMISSION_GRANTED) {
            return false;
        }
    }
    return true;
}

//回调接口
public interface permissionInterface{
    void success();
}
/**
 * 找到没有授权的权限
 * @param activity
 * @param permission
 * @return
 */
public static List<String> findDeniedPermissions(Activity activity, String... permission)
{
    //存储没有授权的权限
    List<String> denyPermissions = new ArrayList<>();
    for (String value : permission)
    {
        if (ContextCompat.checkSelfPermission(activity,value) != PackageManager.PERMISSION_GRANTED)
        {
            //没有权限 就添加
            denyPermissions.add(value);
        }
    }
    return denyPermissions;
}

/**
 * 检测这些权限中是否有 没有授权需要提示的
 * @param activity
 * @param permission
 * @return
 */
public static boolean shouldShowPermissions(Activity activity, String... permission)
{

    for (String value : permission)
    {
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                value))
        {
           return true;
        }
    }
    return false;
}

}`
2.下面在贴一下使用的代码

在需要权限请求的地方调用如下方法就可以开启权限请求
  /**
     * 请求拍照的权限
     * 第二个参数表示一个view ,可以随便传入一个
     * 第三个表示 请求的权限数组
     * 第4个是请求码
     * 第5个是回调接口
     */
    private void requestPermiss() {
        PermissionUtil.checkPermission(getmActivity(), linearAddbankcard2Bankcard, REQUEST_PERMISSIONS, REQUEST_PERMISSION_CODE_TAKE_PIC, new PermissionUtil.permissionInterface() {
            @Override
            public void success() {
                UtilMethod.paizhao(getmActivity(), Constants.PHOTOHRAPH);
            }
        });
    }
但是还得需要重写下面的方法来判断权限是否开启成功,并且做相应的处理
 /**
     * 检测权限的回调
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    public void onRequestPermissionsResult(int requestCode, final String[] permissions, int[] grantResults) {

        if (requestCode == REQUEST_PERMISSION_CODE_TAKE_PIC) {
            if (PermissionUtil.verifyPermissions(grantResults)) {//有权限
                ImageTools.paizhao(getmActivity(), Constants.PHOTOHRAPH);
            } else {
                //没有权限
                if (!PermissionUtil.shouldShowPermissions(this,permissions)) {//这个返回false 表示勾选了不再提示
                    showSnackBar(linearAddbankcard2Bankcard, "请去设置界面设置权限","去设置");
                } else {
                    //表示没有权限 ,但是没勾选不再提示
                    showSnackBar(linearAddbankcard2Bankcard, "请允许权限请求!");
                }
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
    重写下面的方法为了判断, 用户去设置界面是否开启了权限
   @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        //如果是从设置界面返回,就继续判断权限
        if (requestCode == REQUEST_PERMISSION_SEETING) {
            requestPermiss();
        }
    }

3.这时去设置界面的代码

Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", getPackageName(), null);
        intent.setData(uri);
        startActivityForResult(intent, REQUEST_PERMISSION_SEETING);

4.最后提点小建议,最好在申请权限的代码用try catch 住,防止有些厂家修改了系统出现未知的BUG,为了方便使用,我封装了一个请求权限的库,使用非常简单, 一行调用代码即可.具体的参考请求权限的库

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值