Android使用RxPermissions动态申请权限

Android使用RxPermissions动态申请权限

    • 一、目标
      • 1. 效果图
      • 2. 下载地址
    • 二、功能设计
    • 三、准备工作
    • 四、组合起来
      • 1. PermissionHelper
    • 五、Final

一、目标

动态申请运行时权限。

1. 效果图

Android使用RxPermissions动态申请权限_第1张图片

  • 左侧,告知用户权限的用途
  • 右侧,引导用户手动设置权限

2. 下载地址

神马笔记最新版本:【神马笔记 版本1.2.0.apk】

二、功能设计

从Android 6.0(API 23)开始后,部分权限除了需要在AndroidManifest.xml中声明外,还必须在运行时动态申请,比如WRITE_EXTERNAL_STORAGE

因此,涉及到运行时权限相关API时,首先要确保用户授予了应用相应的权限,才能继续执行之后的操作。

三、准备工作

时间紧,任务重。

直接使用第三方开源库来解决这个问题。我们将使用RxPermissions来实现这个功能。

GitHub项目地址:https://github.com/tbruyelle/RxPermissions

四、组合起来

1. PermissionHelper

对RxPermissions做了简单封装,对应三种情况分别做了处理。

  • 已经授予权限,通过回调继续之后操作
  • 需要显示申请,弹出对话框告知用户,并再次请求权限
  • 用户拒绝授权,弹出对话框告知用户,并跳转到应用设置手动开启权限

目前仅支持一种权限,多权限申请可以在这基础上进行扩展。

并且整理了一些国内手机厂商如小米、魅族、华为直接进入权限设置的方式。

(小米测试可用,魅族、华为未进行测试。)

public class PermissionHelper {

    String mPermission;

    CharSequence mRequestMsg;
    CharSequence mDeniedMsg;

    FragmentActivity mContext;

    OnPermissionListener mOnPermissionListener;

    public PermissionHelper(FragmentActivity context) {
        this.mContext = context;
        
        this.mPermission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
        
        this.mRequestMsg = ""; 
        this.mDeniedMsg  = ""; 
    }

    public PermissionHelper setPermission(String permission) {
        this.mPermission = permission;

        return this;
    }

    public PermissionHelper setRequestMessage(CharSequence text) {
        this.mRequestMsg = text;

        return this;
    }

    public PermissionHelper setDeniedMessage(CharSequence text) {
        this.mDeniedMsg = text;

        return this;
    }

    public PermissionHelper setOnPermissionListener(OnPermissionListener listener) {
        this.mOnPermissionListener = listener;

        return this;
    }

    public void request() {
        RxPermissions rxPermission = new RxPermissions(mContext);

        rxPermission.requestEach(mPermission).subscribe(this::accept);
    }

    void accept(Permission permission) {

        if (permission.granted) {

            // 用户已经同意该权限
            if (mOnPermissionListener != null) {
                mOnPermissionListener.onPermissionGranted(this);
            }

        } else if (permission.shouldShowRequestPermissionRationale) {

            // 用户拒绝了该权限,没有选中『不再询问』(Never ask again),那么下次再次启动时,还会提示请求权限的对话框

            DialogInterface.OnClickListener listener = (dialog, which) -> {

                if (which == DialogInterface.BUTTON_POSITIVE) {
                    request();
                } else if (which == DialogInterface.BUTTON_NEGATIVE) {

                }

            };

            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
            builder.setMessage(mRequestMsg);
            builder.setPositiveButton(android.R.string.yes, listener);
            builder.setNegativeButton(android.R.string.cancel, listener);

            AlertDialog dialog = builder.create();
            dialog.setCanceledOnTouchOutside(false);
            dialog.show();

        } else { // 用户拒绝了该权限,并且选中『不再询问』

            DialogInterface.OnClickListener listener = (dialog, which) -> {

                if (which == DialogInterface.BUTTON_POSITIVE) {
                    showSetting(mContext);
                } else if (which == DialogInterface.BUTTON_NEGATIVE) {

                }

            };

            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
            builder.setMessage(mDeniedMsg);
            builder.setPositiveButton(android.R.string.yes, listener);
            builder.setNegativeButton(android.R.string.cancel, listener);
            AlertDialog dialog = builder.create();
            dialog.setCanceledOnTouchOutside(false);
            dialog.show();
        }
    }

    static void showSetting(Context context) {

        if (gotoMiuiPermission(context)) {
            return;
        }

        if (gotoMeizuPermission(context)) {
            return;
        }

        if (gotoHuaweiPermission(context)) {
            return;
        }

        if (gotoAppDetailSetting(context)) {
            return;
        }
    }

    static boolean gotoMiuiPermission(Context context) {

        // MIUI 8

        try {

            Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
            localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
            localIntent.putExtra("extra_pkgname", context.getPackageName());
            context.startActivity(localIntent);

            return true;

        } catch (Exception e) {


        }

        // MIUI 5/6/7

        try {

            Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
            localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
            localIntent.putExtra("extra_pkgname", context.getPackageName());
            context.startActivity(localIntent);

            return true;

        } catch (Exception e1) {

        }

        return false;
    }

    static boolean gotoMeizuPermission(Context context) {

        try {

            Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
            context.startActivity(intent);

            return true;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    static boolean gotoHuaweiPermission(Context context) {

        try {
            Intent intent = new Intent();
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            ComponentName comp = new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity");//华为权限管理
            intent.setComponent(comp);
            context.startActivity(intent);

            return true;

        } catch (Exception e) {
            e.printStackTrace();

        }

        return false;
    }

    static boolean gotoAppDetailSetting(Context context) {
        Intent localIntent = new Intent();
        localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (Build.VERSION.SDK_INT >= 9) {
            localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
            localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
        } else if (Build.VERSION.SDK_INT <= 8) {
            localIntent.setAction(Intent.ACTION_VIEW);
            localIntent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
            localIntent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName());
        }

        try {
            context.startActivity(localIntent);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     *
     */
    public interface OnPermissionListener {

        void onPermissionGranted(PermissionHelper helper);
    }
}

五、Final

RxPermissions工作良好,没有机会探究Android运行时权限的相关代码。

~幸甚至哉~幸甚至哉~

你可能感兴趣的:(神马笔记)