Android 6.0动态添加权限(Finn_ZengYuan博客)

1,随着手机版本变高,各种权限也有所限制;以下代码可人性化添加动态权限;

 

权限工具类1,2,3,4:

1,FinnPermissionConfig.CLass

package com.finn.tools.finnpermission;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Author  : Finn
 * E-mail  : 892603597@qq.com
 * Date    : 2019/12/5 16:03
 * Blog    : https://www.cnblogs.com/finn21/
 * Describe:
 * TODO    :
 */
public class FinnPermissionConfig implements Parcelable {
    //必须要所有的权限都通过才能通过
    private boolean forceAllPermissionsGranted;
    //设置用户点击不再提示之后的弹窗文案
    private String forceDeniedPermissionTips;

    public String getForceDeniedPermissionTips() {
        return forceDeniedPermissionTips;
    }

    public FinnPermissionConfig setForceDeniedPermissionTips(String forceDeniedPermissionTips) {
        this.forceDeniedPermissionTips = forceDeniedPermissionTips;
        return this;
    }

    private FinnPermissionUtils check;

    public FinnPermissionConfig(FinnPermissionUtils check) {
        this.check = check;
    }

    public boolean isForceAllPermissionsGranted() {
        return forceAllPermissionsGranted;
    }

    public FinnPermissionConfig setForceAllPermissionsGranted(boolean forceAllPermissionsGranted) {
        this.forceAllPermissionsGranted = forceAllPermissionsGranted;
        return this;
    }

    public FinnPermissionUtils buildConfig() {
        return check;
    }


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeByte(this.forceAllPermissionsGranted ? (byte) 1 : (byte) 0);
        dest.writeString(this.forceDeniedPermissionTips);
    }

    protected FinnPermissionConfig(Parcel in) {
        this.forceAllPermissionsGranted = in.readByte() != 0;
        this.forceDeniedPermissionTips = in.readString();
    }

    public static final Creator<FinnPermissionConfig> CREATOR = new Creator<FinnPermissionConfig>() {
        @Override
        public FinnPermissionConfig createFromParcel(Parcel source) {
            return new FinnPermissionConfig(source);
        }

        @Override
        public FinnPermissionConfig[] newArray(int size) {
            return new FinnPermissionConfig[size];
        }
    };
}

 

2,FinnPermissionFragment.Class

package com.finn.tools.finnpermission;


import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;

import java.util.ArrayList;
import java.util.List;

import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;

/***/
public class FinnPermissionFragment extends Fragment {
    private String[] permissions = null;
    public static final int PERMISSION_REQUEST_CODE = 1001;
    public static final int REQUEST_PERMISSION_SETTING = 1002;
    private FinnPermissionListener permissionCheckListener;
    private Activity mContext;

    private FinnPermissionConfig checkConfig;

    private String forceDeniedPermissionTips = "";

    public FinnPermissionFragment setPermissionCheckListener(FinnPermissionListener listener) {
        this.permissionCheckListener = listener;
        return this;
    }

    public static FinnPermissionFragment newInstance(String[] permissions, FinnPermissionConfig checkConfig) {
        Bundle args = new Bundle();
        args.putStringArray("permissions", permissions);
        args.putParcelable("config", checkConfig);
        FinnPermissionFragment fragment = new FinnPermissionFragment();
        fragment.setArguments(args);
        return fragment;
    }

    /**
     * 开始请求
     */
    public void start(Activity activity) {
        if (activity != null) {
            mContext = activity;
            if (Looper.getMainLooper() != Looper.myLooper()) {
                return;
            }
            activity.getFragmentManager().beginTransaction().add(
                    this, activity.getClass().getName()).commit();
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        forceDeniedPermissionTips = "请前往设置->应用->【"
                + FinnPermissionUtils.getAppName(mContext)
                + "】->权限中打开相关权限,否则功能无法正常运行!";

        //获取传输过来的权限
        permissions = this.getArguments().getStringArray("permissions");
        checkConfig = this.getArguments().getParcelable("config");

        if (checkConfig != null && TextUtils.isEmpty(checkConfig.getForceDeniedPermissionTips())) {
            checkConfig.setForceDeniedPermissionTips(forceDeniedPermissionTips);
        }

        if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.M)) {
            requestPermissionsSuccess();
        } else {
            requestPermission();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            //记录点击了不再提醒的未授权权限
            List<String> forceDeniedPermissions = new ArrayList<>();
            //记录点击了普通的未授权权限
            List<String> normalDeniedPermissions = new ArrayList<>();
            List<String> grantedPermissions = new ArrayList<>();
            for (int i = 0; i < grantResults.length; i++) {
                int grantResult = grantResults[i];
                String permission = permissions[i];
                if (grantResult == PackageManager.PERMISSION_GRANTED) {
                    //授权通过 nothing to do
                    grantedPermissions.add(permission);
                } else {
                    //授权拒绝
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(mContext, permission)) {
                        forceDeniedPermissions.add(permission);
                    } else {
                        normalDeniedPermissions.add(permission);
                    }
                }
            }
            if (forceDeniedPermissions.size() == 0 && normalDeniedPermissions.size() == 0) {
                //全部授权通过
                requestPermissionsSuccess();
            } else {
                //部分授权通过 如果用户希望一直提示授权直到给权限位置 那么就一直去请求权限
                if (checkConfig != null && checkConfig.isForceAllPermissionsGranted()) {
                    if (normalDeniedPermissions.size() != 0) {
                        //还有普通拒绝的权限可以弹窗
                        requestPermission();
                    } else {
                        //所有没有通过的权限都是用户点击了不再提示的 我擦 这里本来是想把未授权的所有权限的名称列出来展示的 后来想想觉得配置有点麻烦
//                        StringBuilder deniedString = new StringBuilder();
//                        for (String forceDeniedPermission : forceDeniedPermissions) {
//                            deniedString.append(forceDeniedPermission + ",");
//                        }
//                        String denied = deniedString.substring(0, deniedString.length() - 1);
                        new AlertDialog.Builder(mContext)
                                .setTitle(mContext.getString(R.string.permissions_check_warn))//警告
                                .setMessage(checkConfig == null ? forceDeniedPermissionTips : checkConfig.getForceDeniedPermissionTips())
                                .setCancelable(false)
                                .setPositiveButton(mContext.getString(R.string.permissions_check_ok), new DialogInterface.OnClickListener() {//确定
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        openSettingPage();
                                    }
                                }).show();
                    }
                } else {
                    for (String permission : this.permissions) {
                        if (grantedPermissions.contains(permission)
                                || normalDeniedPermissions.contains(permission)
                                || forceDeniedPermissions.contains(permission)) {

                        } else {
                            //如果三者都不包含他 包名这个权限不是隐私权限 直接给就完事了 所以要放到已授权的权限列表里面去
                            grantedPermissions.add(permission);
                        }
                    }
                    requestPermissionsFail(grantedPermissions.toArray(new String[grantedPermissions.size()]),
                            normalDeniedPermissions.toArray(new String[normalDeniedPermissions.size()]),
                            forceDeniedPermissions.toArray(new String[forceDeniedPermissions.size()]));
                }
            }
        }
    }

    private void openSettingPage() {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", mContext.getPackageName(), null);
        intent.setData(uri);
        startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
    }

    private void requestPermissionsSuccess() {
        if (permissionCheckListener != null) {
            permissionCheckListener.permissionRequestSuccess();
        }
        mContext.getFragmentManager().beginTransaction().remove(this).commit();
    }

    private void requestPermissionsFail(String[] grantedPermissions, String[] deniedPermissions, String[] forceDeniedPermissions) {
        if (permissionCheckListener != null) {
            permissionCheckListener.permissionRequestFail(grantedPermissions, deniedPermissions, forceDeniedPermissions);
        }
        mContext.getFragmentManager().beginTransaction().remove(this).commit();
    }

    /**
     * 获取权限
     */
    @TargetApi(Build.VERSION_CODES.M)
    public void requestPermission() {
        //记录未授权的权限
        List<String> deniedPermissions = new ArrayList<>();
        for (String permission : permissions) {
            int check = ContextCompat.checkSelfPermission(getActivity(), permission);
            if (check == PackageManager.PERMISSION_GRANTED) {
                //授权通过了已经 do nothing
            } else {
                deniedPermissions.add(permission);
            }
        }
        if (deniedPermissions.size() != 0) {
            //有权限没有通过
            requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), PERMISSION_REQUEST_CODE);
        } else {
            //授权全部通过
            requestPermissionsSuccess();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_PERMISSION_SETTING) {
            //设置页面回来了
            requestPermission();
        }
    }
}

 

3, FinnPermissionListener.Class

package com.finn.tools.finnpermission;

/**
 * Author  : Finn
 * E-mail  : 892603597@qq.com
 * Date    : 2019/12/5 16:03
 * Blog    : https://www.cnblogs.com/finn21/
 * Describe:
 * TODO    :
 * @desc: 授权反馈事件
 */
public interface FinnPermissionListener {
    /*
     * 授权全部通过
     */
    void permissionRequestSuccess();

    /*
     * 授权未通过
     * @param grantedPermissions 已通过的权限
     * @param deniedPermissions 拒绝的权限
     * @param forceDeniedPermissions 永久拒绝的权限(也就是用户点击了不再提醒的那些权限)
     */
    void permissionRequestFail(String[] grantedPermissions, String[] deniedPermissions, String[] forceDeniedPermissions);
}

 

4,  FinnPermissionUtils.Class 

package com.finn.tools.finnpermission;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;

import java.util.ArrayList;
import java.util.List;
/**
 * Author  : Finn
 * E-mail  : 892603597@qq.com
 * Date    : 2019/12/5 16:03
 * Blog    : https://www.cnblogs.com/finn21/
 * Describe:
 * TODO    :
 * @desc: 权限检查主要帮助类
 */
public class FinnPermissionUtils {
    //宿主Activity
    private Activity mContext;
    //回调监听
    private FinnPermissionListener listener;
    //存储所有的权限列表
    private List<String> permissions = new ArrayList<>();

    private FinnPermissionConfig checkConfig;

    private FinnPermissionUtils(Activity mContext) {
        this.mContext = mContext;
    }

    public static FinnPermissionUtils with(Activity context) {
        return new FinnPermissionUtils(context);
    }

    public FinnPermissionConfig createConfig() {
        checkConfig = new FinnPermissionConfig(this);
        return checkConfig;
    }

    /**
     * 添加权限
     * @param permission
     */
    public FinnPermissionUtils addPermissions(String permission) {
        if (!permissions.contains(permission))
            permissions.add(permission);
        return this;
    }

    /**
     * 添加权限监听
     * @param listener
     */
    public FinnPermissionUtils setPermissionsCheckListener(FinnPermissionListener listener) {
        this.listener = listener;
        return this;
    }

    /**
     * 开始申请权限
     */
    public void startCheckPermission() {
        FinnPermissionFragment.newInstance(permissions.toArray(new String[permissions.size()]), checkConfig).setPermissionCheckListener(listener).start(mContext);
    }

    /**
     * 获取App的名称
     *
     * @param context 上下文
     * @return 名称
     */
    public static String getAppName(Context context) {
        PackageManager pm = context.getPackageManager();
        //获取包信息
        try {
            PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), 0);
            //获取应用 信息
            ApplicationInfo applicationInfo = packageInfo.applicationInfo;
            //获取albelRes
            int labelRes = applicationInfo.labelRes;
            //返回App的名称
            return context.getResources().getString(labelRes);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }
}

 

以上为工具类,现在我们来在Activity里面调用权限,其实很简单就是一段调用代码就行;

 

 FinnPermissionUtils.with(MainActivity.this)
                        //添加所有你需要申请的权限
                        .addPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        .addPermissions(Manifest.permission.ACCESS_FINE_LOCATION)
                        .addPermissions(Manifest.permission.CALL_PHONE)
                        .addPermissions(Manifest.permission.ACCESS_WIFI_STATE)
                        .addPermissions(Manifest.permission.CAMERA)
                        //添加权限申请回调监听 如果申请失败 会返回已申请成功的权限列表,用户拒绝的权限列表和用户点击了不再提醒的永久拒绝的权限列表
                        .setPermissionsCheckListener(new FinnPermissionListener() {
                            @Override
                            public void permissionRequestSuccess() {
                                //所有权限授权成功才会回调这里
                    
                                Toast.makeText(MainActivity.this, "所有权限都授权成功", Toast.LENGTH_SHORT).show();
                            }

                            @Override
                            public void permissionRequestFail(String[] grantedPermissions, String[] deniedPermissions, String[] forceDeniedPermissions) {
                                //当有权限没有被授权就会回调这里
                                StringBuilder result = new StringBuilder("授权结果\n授权失败\n\n");
                                result.append("授权通过的权限:\n");
                                for (String grantedPermission : grantedPermissions) {
                                    result.append(grantedPermission + "\n");
                                }
                                result.append("\n临时拒绝的权限:\n");
                                for (String deniedPermission : deniedPermissions) {
                                    result.append(deniedPermission + "\n");
                                }
                                result.append("\n永久拒绝的权限:\n");
                                for (String forceDeniedPermission : forceDeniedPermissions) {
                                    result.append(forceDeniedPermission + "\n");
                                }
                             
                                Toast.makeText(MainActivity.this, "授权失败", Toast.LENGTH_SHORT).show();
                            }
                        })
                        //生成配置
                        .createConfig()
                        //配置是否强制用户授权才可以使用,当设置为true的时候,如果用户拒绝授权,会一直弹出授权框让用户授权
                        .setForceAllPermissionsGranted(aSwitch.isChecked())
                        //配置当用户点击了不再提示的时候,会弹窗指引用户去设置页面授权,这个参数是弹窗里面的提示内容
                        .setForceDeniedPermissionTips("请前往设置->应用->【" + FinnPermissionUtils.getAppName(MainActivity.this) + "】->权限中打开相关权限!")
                        //构建配置并生效
                        .buildConfig()
                        //开始授权
                        .startCheckPermission();

 

posted on 2020-09-28 10:13  Finn_ZengYuan  阅读(268)  评论(1编辑  收藏  举报