今天遇到了个问题,其实原来也遇到过,但是好长时间没有碰到了,有些遗忘。今天正好有点空,特整理下申请流程

权限动态申请流程:

1、检查是否获取该权限

int result = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);

检查后会返回响应值,如果未授予需要我们手动申请

2、申请权限/先弹框解释在申请

final String[] pers = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
                    requestPermissions(pers, LOCATION);

因为我们产品定的流程是先弹自己的dialog框解释,用户点了确定再去请求,所以我多了一步就是弹了个框。

3、获取结果,做下一步处理

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == LOCATION) {
            ArrayList<String> deniedPermissionList = new ArrayList();

            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    deniedPermissionList.add(permissions[i]);
                }
            }

            if (deniedPermissionList.isEmpty()) {
                //已经全部授权
                startLocation();
            } else {
                //勾选了对话框中”Don’t ask again”的选项, 返回false
                for (String deniedPermission : deniedPermissionList) {
                    boolean flag = shouldShowRequestPermissionRationale(deniedPermission);
                    if (!flag) {
                        // todo 拒绝授权并打了勾不再提示
                        goSystemSettingPage();
                        return;
                    }
                }
                //拒绝授权
                checkLocationPermission();
            }
        }
    }

这里有两种情况:1、用户点了拒绝了但未勾选下次不再提醒

                             2、用户点了拒绝并且勾选了下次不再提醒

我的处理是,当第一种情况时,再次弹起解释框让用户授权,第二种时跳转系统设置页面(因为在申请系统就不能再调起系统授权框了),这样可能比较暴力,但也没什么好办法,接的别人的老代码,里边有20多处调用接口都用到了经纬度。

遇到的坑:

1、一部分手机关闭gps也没关系,可以通过基站定位到位置,但比较新版本的手机关闭了系统位置信息服务那就gg了,所以还要做相关处理

/**
     * 处理关闭系统定位服务
     */
    private boolean dealNoSysytemLocationPermission() {
        boolean locationEnabled = CheckPermissionLocation.INSTANCE.isLocationEnabled(this.getApplicationContext());
        if (!locationEnabled) { // 用户关闭了系统定位服务
            // 跳转开启系统定位页面
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
            return true;
        }
        return false;
    }

2、部分相对低端的手机拒绝了权限后在check的时候一样会返回true告诉你你的app已经有了该权限,这个比较恶心,比如我测到的红米部分手机和vivo部分手机都是这样,这就没办法了,还想要获取到该权限,我这边是这么做的。先定位,如果定位失败了直接跳转系统页让用户自己开启我们app的定位权限

Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", this.getPackageName(), null);
        intent.setData(uri);
        try {
            this.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }

后续:

我获取把代码替换了,简单调研了下github上的权限申请库,RxPermission、google自己的easypermissions和PermissionDispatcher。用户原理各有特点但大同小异,这里就不赘述了。个人还是比较喜欢最后一个,所以用了它,大家可以自行选择

RxPermission

easypermissions

PermissionsDispatcher