权限请求工具类

Author Avatar
发达 7月 27, 2018
  • 在其它设备中阅读本文章

基于第三方框架AndPermission

def permission_version = "2.0.0-rc11"
implementation "com.yanzhenjie:permission:$permission_version"

工具类源码,使用方法在最底部

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;

import com.yanzhenjie.permission.Action;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.SettingService;

import java.util.List;

/**
 * @author : fada
 * Date : 2018/7/27
 * Description : 权限工具类
 */
public class PermissionsUtils {
    public static final String DEFAULT_MESSAGE = "拒绝此权限后您将无法继续使用APP,请同意该权限";
    /**
     * 允许应用程序读取用户的日历数据。
     */
    public static final String PERMISSION_READ_CALENDAR = Manifest.permission.READ_CALENDAR;
    /**
     * 允许应用程序写入用户的日历数据。
     */
    public static final String PERMISSION_WRITE_CALENDAR = Manifest.permission.WRITE_CALENDAR;

    //permission group:CALENDA 用于与用户日历相关的运行时权限。
    /**
     * 要求能够访问摄像机设备
     * 这将自动执行所有相机功能的}清单元素。如果您不需要所有相机功能,或者在相机不可用时无法正常操作,则必须根据需要修改清单,以便安装在不支持所有相机功能的设备上。
     */
    public static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;
    /**
     * 允许应用程序写入用户的联系人数据。
     */
    public static final String PERMISSION_WRITE_CONTACTS = Manifest.permission.WRITE_CONTACTS;

    //permission group:CAMERA 用于与访问摄像头或从设备捕捉图像/视频相关联的权限。
    /**
     * 允许应用程序读取用户的联系人数据。
     */
    public static final String PERMISSION_READ_CONTACTS = Manifest.permission.READ_CONTACTS;


    //permission group:CONTACTS 用于与此设备上的联系人和配置文件相关的运行时权限。
    /**
     * 允许访问帐户服务中的帐户列表。GMail账户列表?
     */
    public static final String PERMISSION_GET_ACCOUNTS = Manifest.permission.GET_ACCOUNTS;
    /**
     * 允许应用程序访问精确的位置。
     */
    public static final String PERMISSION_ACCESS_FINE_LOCATION = Manifest.permission
            .ACCESS_FINE_LOCATION;
    /**
     * 允许应用程序访问近似位置。
     */
    public static final String PERMISSION_ACCESS_COARSE_LOCATION = Manifest.permission
            .ACCESS_COARSE_LOCATION;

    //permission group:LOCATION 用于允许访问设备位置的权限。
    /**
     * 允许应用程序录制音频。
     */
    public static final String PERMISSION_RECORD_AUDIO = Manifest.permission.RECORD_AUDIO;
    /**
     * 允许只读访问电话状态, 包括设备的电话号码、当前的蜂窝网络信息、任何正在进行的呼叫的状态以及设备上注册的任何 PhoneAccounts 的列表
     */
    public static final String PERMISSION_READ_PHONE_STATE = Manifest.permission.READ_PHONE_STATE;

    //permission group:MICROPHONE 用于与从设备访问麦克风音频相关的权限。请注意, 电话也会捕获音频, 但位于单独的 (更可见) 权限组中。
    /**
     * 允许应用程序在不经过拨号用户界面的情况下启动电话呼叫, 以便用户确认呼叫。
     */
    public static final String PERMISSION_CALL_PHONE = Manifest.permission.CALL_PHONE;

    //permission group:PHONE 用于关联的电话功能的权限。
    /**
     * 允许应用程式读取使用者的通话记录。
     */
    public static final String PERMISSION_READ_CALL_LOG = Manifest.permission.READ_CALL_LOG;
    /**
     * 允许应用程序写入(但不读取)用户的通话记录数据。
     */
    public static final String PERMISSION_WRITE_CALL_LOG = Manifest.permission.WRITE_CALL_LOG;
    /**
     * 允许应用程序将语音邮件添加到系统中。
     */
    public static final String PERMISSION_ADD_VOICEMAIL = Manifest.permission.ADD_VOICEMAIL;
    /**
     * 允许应用程序使用SIP服务。
     */
    public static final String PERMISSION_USE_SIP = Manifest.permission.USE_SIP;
    /**
     * 允许应用程序查看在拨出电话期间拨打的号码,并可选择将呼叫重定向到其他号码或完全中止呼叫。
     */
    public static final String PERMISSION_PROCESS_OUTGOING_CALLS = Manifest.permission
            .PROCESS_OUTGOING_CALLS;
    /**
     * 允许该应用接听来电。
     */
    public static final String PERMISSION_ANSWER_PHONE_CALLS = Manifest.permission
            .ANSWER_PHONE_CALLS;
    /**
     * 允许读取设备的电话号码。这是由READ_PHONE_STATE授予的功能的一部分,但暴露于即时应用程序。
     */
    public static final String PERMISSION_READ_PHONE_NUMBERS = Manifest.permission
            .READ_PHONE_NUMBERS;
    /**
     * 允许应用程序访问用户用来测量他/她身体内发生的事情的传感器的数据,例如心率。
     */
    public static final String PERMISSION_BODY_SENSORS = Manifest.permission.BODY_SENSORS;
    /**
     * 允许应用程式发送短讯。
     */
    public static final String PERMISSION_SEND_SMS = Manifest.permission.SEND_SMS;

    //permission group:SENSORS 用于与访问人体或环境传感器相关的权限。
    /**
     * 允许应用程式接收短讯。
     */
    public static final String PERMISSION_RECEIVE_SMS = Manifest.permission.RECEIVE_SMS;

    //permission group:SMS 用于与用户的SMS消息相关的运行时权限。
    /**
     * 允许应用程式读取短讯。
     */
    public static final String PERMISSION_READ_SMS = Manifest.permission.READ_SMS;
    /**
     * 允许应用程序接收 WAP 推送消息。
     */
    public static final String PERMISSION_RECEIVE_WAP_PUSH = Manifest.permission
            .RECEIVE_WAP_PUSH;
    /**
     * 允许应用程序监视传入彩信消息。
     */
    public static final String PERMISSION_RECEIVE_MMS = Manifest.permission.RECEIVE_MMS;
    /**
     * 允许应用程序从外部存储中读取。
     * 任何声明 WRITE_EXTERNAL_STORAGE 权限的应用程序都被隐式授予此权限。
     * 此权限是从 API 级别19开始执行的。在 API 级别19之前, 此权限没有强制执行, 并且所有应用程序仍然可以从外部存储读取。您可以通过在运行 Android 4.1
     * 或更高的设备上的 '设置' 应用程序中的
     * '开发人员选项' 中启用 '保护 USB 存储' 来测试您的应用程序。
     * 也从 API 级别19开始, 在 getExternalFilesDir (string) 和 getExternalCacheDir () 返回的应用程序特定目录中读写文件时,
     * 不需要此权限。
     */
    public static final String PERMISSION_READ_EXTERNAL_STORAGE = Manifest.permission
            .READ_EXTERNAL_STORAGE;
    /**
     * 允许应用程序写入外部存储。
     * 从 API 级别19开始, 在 getExternalFilesDir (String) 和 getExternalCacheDir () 返回的应用程序特定目录中读写文件时,
     * 不需要此权限。
     */
    public static final String PERMISSION_WRITE_EXTERNAL_STORAGE = Manifest.permission
            .WRITE_EXTERNAL_STORAGE;


    //permission group:STORAGE 用于与共享外部存储相关的运行时权限。
    private static final String BUTTON_POSITIVE_TEXT = "允许";
    private static final String BUTTON_NEGATIVE_TEXT = "拒绝";
    /**
     * 书否需要继续请求,当用户拒绝后继续请求,表示此权限特别重要
     */
    private boolean mNeedAgain;
    /**
     * 继续请求的信息,用来告诉用户这个权限干嘛的,拒绝会怎样
     */
    private String mMessage;
    /**
     * 接口回调,必须参数
     */
    private PermissionCallBack mPermissionCallBack;
    /**
     * 需要请求的权限,必须参数
     */
    private String[] mPermissions;

    /**
     * 构造函数
     *
     * @param needAgain          参数见 {@link Build#needAgain}
     * @param message            参数见 {@link Build#message}
     * @param permissionCallBack 参数见 {@link Build#permissionCallBack}
     * @param permissions        参数见 {@link Build#permissions}
     */
    private PermissionsUtils(boolean needAgain, String message, PermissionCallBack
            permissionCallBack, String[]
                                     permissions) {
        mNeedAgain = needAgain;
        mMessage = message;
        mPermissionCallBack = permissionCallBack;
        mPermissions = permissions;
    }

    /**
     * {@link Activity}
     * activity
     *
     * @param activity activity
     */
    public void getPermission(Activity activity) {
        checkNull(activity);
        getPermissions(activity);
    }

    /**
     * 判断是否是空
     *
     * @param object
     */
    private static void checkNull(Object object) {
        if (object == null) {
            throw new NullPointerException("null : " + object);
        }
    }

    /**
     * 获取运行时权限
     *
     * @param context 封装后的请求类
     */
    public void getPermissions(final Context context) {
        //检查callback是否为空
        checkNull(mPermissionCallBack);
        //检查权限是否是空
        checkLength(mPermissions);
        AndPermission
                .with(context)
                .runtime()
                .permission(mPermissions)
                .onGranted(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> data) {
                        //用户同意,用户同意了你的权限
                        mPermissionCallBack.granted();
                    }
                })
                .onDenied(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> permissions) {
                        //用户拒绝了你的权限
                        if (AndPermission.hasAlwaysDeniedPermission(context, permissions)) {
                            if (mNeedAgain) {
                                //再次请求
                                againPermission(context);
                            } else {
                                //不再提示
                                mPermissionCallBack.noAgain();
                            }
                        } else {
                            //用户拒绝
                            mPermissionCallBack.refuse();
                        }
                    }
                })
                .start();

    }

    /**
     * 检查数据长度是否为空
     *
     * @param objects
     */
    private static void checkLength(Object[] objects) {
        if (objects == null || objects.length < 1) {
            throw new NullPointerException("null : " + objects);
        }
    }

    /**
     * 再次申请权限
     *
     * @param context
     */
    private void againPermission(final Context context) {
        if (AndPermission.hasAlwaysDeniedPermission(context, mPermissions)) {
            final SettingService settingService = AndPermission.permissionSetting(context);

            // 这里使用一个Dialog展示没有这些权限应用程序无法继续运行,询问用户是否去设置中授权。
            ProgressDialog progressDialog = new ProgressDialog(context);
            progressDialog.setMessage(mMessage);
            progressDialog.setButton(AlertDialog.BUTTON_POSITIVE, BUTTON_POSITIVE_TEXT, (new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                    //如果用户同意去设置:
                    settingService.execute();
                }
            }));
            progressDialog.setButton(AlertDialog.BUTTON_NEGATIVE, BUTTON_NEGATIVE_TEXT, new
                    DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // 如果用户不同意去设置:
                            settingService.cancel();
                            mPermissionCallBack.noAgain();
                        }
                    });
            progressDialog.show();
        }
    }

    /**
     * {@link Context}
     *
     * @param context 上下文
     */
    public void getPermission(Context context) {
        checkNull(context);
        getPermissions(context);
    }

    /**
     * {@link android.support.v4.app.Fragment}
     *
     * @param fragment fragment
     */
    public void getPermission(android.support.v4.app.Fragment fragment) {
        checkNull(fragment);
        getPermissions(fragment.getActivity());
    }

    /**
     * {@link android.app.Fragment}
     *
     * @param fragment fragment
     */
    public void getPermission(android.app.Fragment fragment) {
        checkNull(fragment);
        getPermissions(fragment.getActivity());
    }

    /**
     * @author fada
     * @date 18-2-26
     * 权限回调类
     */
    public interface PermissionCallBack {
        /**
         * 用户同意了权限
         */
        void granted();

        /**
         * 用户拒绝了权限
         */
        void refuse();

        /**
         * 用户拒绝了权限,并点击不再询问
         */
        void noAgain();
    }

    public static class Build {
        /**
         * 是否需要继续请求,当用户拒绝后继续请求,表示此权限特别重要
         */
        private boolean needAgain = false;
        /**
         * 继续请求的信息,用来告诉用户这个权限干嘛的,拒绝会怎样
         */
        private String message = DEFAULT_MESSAGE;
        /**
         * 接口回调,必须参数
         */
        private PermissionCallBack permissionCallBack;
        /**
         * 需要请求的权限,必须参数
         */
        private String[] permissions;

        public Build() {
        }

        /**
         * @param needAgain {@link Build#needAgain}
         * @return 当前类
         */
        public Build needAgain(boolean needAgain) {
            this.needAgain = needAgain;
            return this;
        }

        /**
         * @param message {@link Build#message}
         * @return 当前类
         */
        public Build message(String message) {
            this.message = message;
            return this;
        }

        /**
         * @param permissionCallBack {@link Build#permissionCallBack}
         * @return 当前类
         */
        public Build permissionCallBack(PermissionCallBack permissionCallBack) {
            this.permissionCallBack = permissionCallBack;
            return this;
        }

        /**
         * @param permissions {@link Build#permissions}
         * @return 当前类
         */
        public Build permissions(String... permissions) {
            this.permissions = permissions;
            return this;
        }

        public PermissionsUtils build() {
            return new PermissionsUtils(needAgain, message, permissionCallBack, permissions);
        }
    }
}

使用

new PermissionsUtils
        .Build()
        //哪些权限
        .permissions(PermissionsUtils.PERMISSION_CAMERA, PermissionsUtils
                .PERMISSION_READ_EXTERNAL_STORAGE)
        //是否需要继续请求
        .needAgain(true)
        //拒绝时的提示消息
        .message("拒绝该权限将导致应用无法继续使用,是否确定")
        //回调
        .permissionCallBack(new PermissionsUtils.PermissionCallBack() {
            @Override
            public void granted() {
                //获取权限
            }
            @Override
            public void refuse() {
                //被拒绝
            }
            @Override
            public void noAgain() {
                //不再提示
            }
        })
        .build()
        .getPermission(this);