Android 动态获取权限

1.动态权限发射器

/**
 * Description : 动态权限发射器
 */
public final class DynamicPermissionEmitter {

    private static final String TAG = "DynamicPermissionEmitter";

    /**
     * 申请权限的回调
     */
    public interface ApplyPermissionsCallback {
        /**
         * 权限以map形式返回
         *
         * @param permissionEntityMap key value 形式 存储权限实体类,key 为权限名称
         */
        void applyPermissionResult(Map<String, DynamicPermissionEntity> permissionEntityMap);
    }

    /**
     * 动态权限申请的 fragment TAG
     */
    private static final String DYNAMIC_PERMISSION_FRAGMENT_TAG = "DynamicPermissionFragment";

    /**
     * 动态权限Fragment
     */
    private DynamicPermissionFragment dynamicPermissionFragment;
    /**
     * fragment manager
     */
    private FragmentManager fragmentManager;

    /**
     * 构造方法
     *
     * @param activity fragmentActivity
     */
    public DynamicPermissionEmitter(@NonNull FragmentActivity activity) {
        try {
            generateApplyPermissionFragment(activity.getSupportFragmentManager());

        } catch (Exception e) {
            handleFragmentException(activity, e);
        }
    }

    /**
     * 构造方法
     *
     * @param fragment v4 包下的 fragment
     */
    @SuppressLint("LongLogTag")
    public DynamicPermissionEmitter(@NonNull Fragment fragment) {
        try {
            generateApplyPermissionFragment(fragment.getChildFragmentManager());
        } catch (Exception e) {
            Log.e(TAG, "DynamicPermissionEmitter fragment", e);
        }
    }


    /**
     * 用户可能不知道当前是activity还是context 直接通过context转化成FragmentActivity
     *
     * @param activity fragment
     * @param e        exception
     */
    @SuppressLint("LongLogTag")
    private void handleFragmentException(@NonNull FragmentActivity activity, Exception e) {
        FragmentManager supportFragmentManager = activity.getSupportFragmentManager();
        if (supportFragmentManager != null) {
            List<Fragment> fragments = supportFragmentManager.getFragments();
            if (fragments != null) {
                for (int i = 0; i < fragments.size(); i++) {
                    Fragment fragment = fragments.get(i);
                    if (TAG.equals(fragment.getTag())) {
                        continue;
                    }
                    try {
                        generateApplyPermissionFragment(fragment.getChildFragmentManager());
                    } catch (Exception e1) {
                        Log.e(TAG, "DynamicPermissionEmitter activity", e);
                    }
                    break;
                }
            }
        }
    }

    /**
     * 生成申请权限的fragment
     *
     * @param fragmentManager fragmentManager
     */
    private void generateApplyPermissionFragment(@NonNull FragmentManager fragmentManager) throws Exception {
        this.fragmentManager = fragmentManager;
        Fragment mFragment = fragmentManager.findFragmentByTag(DYNAMIC_PERMISSION_FRAGMENT_TAG);
        // 保证一个activity 或 fragment 只添加一个permission fragment
        if (mFragment != null) {
            dynamicPermissionFragment = (DynamicPermissionFragment) mFragment;
        } else {
            dynamicPermissionFragment = DynamicPermissionFragment.newInstance();
            fragmentManager
                    .beginTransaction()
                    .add(dynamicPermissionFragment, DYNAMIC_PERMISSION_FRAGMENT_TAG)
                    .commitNow();
        }
    }


    /**
     * 发射权限 不需要回调,只需要检查权限向系统申请权限
     *
     * @param permissions 权限数组
     */
    public void emitterPermission(String... permissions) {
        emitterPermission(null, permissions);
    }

    /**
     * 发射权限
     *
     * @param applyPermissionsCallback 回调
     * @param permissions              权限数组
     */
    @SuppressLint("LongLogTag")
    public void emitterPermission(ApplyPermissionsCallback applyPermissionsCallback, String... permissions) {

        if (permissions == null || permissions.length == 0) {
            throw new NullPointerException("permissions no nulls allowed...");
        }
        try {
            if (dynamicPermissionFragment == null && fragmentManager != null) {
                generateApplyPermissionFragment(fragmentManager);
            }
            if (dynamicPermissionFragment != null) {
                dynamicPermissionFragment.checkRegisteredPermissionInManifest(permissions);
                dynamicPermissionFragment.setApplyPermissionsCallback(applyPermissionsCallback);
                dynamicPermissionFragment.commitPermission(permissions);
            }
        } catch (Exception e) {
            Log.e(TAG, "emitterPermission", e);
        }
    }

    /**
     * 判断是否有某个权限
     *
     * @param context    context
     * @param permission 权限名称
     * @return 是否有某个存储权限
     */
    public static boolean hasPermission(@NonNull Context context, String permission) {
        return Build.VERSION.SDK_INT < 23
                || PermissionChecker.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
    }

}

2.权限的实体类

/**
 * Description : 权限的实体类
 */

public final class DynamicPermissionEntity {


    //拒绝了此权限
    public static final int PERMISSION_DENIED = 1;
    //授予了权限
    public static final int PERMISSION_GRANTED = 2;
    //拒绝了此权限并且勾选了不在提示
    public static final int PERMISSION_DENIED_AND_SELECTED_NO_PROMPT = 3;
    //不能处理的权限 例如android 6.0 以下手机,请用try catch 捕获无权限的异常
    public static final int PERMISSION_UN_HANDLE = 4;

    // 权限名称
    private String permissionName;
    // 权限状态,默认为被拒绝的权限
    private int permissionState = PERMISSION_DENIED;

    public String getPermissionName() {
        return permissionName;
    }

    public void setPermissionName(String permissionName) {
        this.permissionName = permissionName;
    }

    public int getPermissionState() {
        return permissionState;
    }

    public void setPermissionState(int permissionState) {
        this.permissionState = permissionState;
    }

    /**
     * 6.0 以下也默认为已经有权限
     *
     * @return 是否授予了某项权限
     */
    public boolean isGranted() {
        return permissionState == PERMISSION_GRANTED || permissionState == PERMISSION_UN_HANDLE;
    }

    /**
     * 用户已经勾选了不在提示
     *
     * @return 是否应该给用户一个友好的提示
     */
    public boolean shouldShowRequestPermissionRational() {
        return permissionState == PERMISSION_DENIED_AND_SELECTED_NO_PROMPT;
    }

    @Override
    public String toString() {
        return "DynamicPermissionEntity{" +
                "permissionName='" + permissionName + '\'' +
                ", permissionState=" + permissionState +
                '}';
    }
}

3.申请权限的fragment

/**
 * Description : 申请权限的fragment
 */

public final class DynamicPermissionFragment extends Fragment {

    // 权限的请求码
    private static final int REQUEST_PERMISSION_CODE = 1000;
    private static final String TAG = "DynamicPermissionFragment";

    // activity
    private Activity activity;
    // 申请权限的回调
    private DynamicPermissionEmitter.ApplyPermissionsCallback applyPermissionsCallback;
    // 存放动态权限实体类与权限名称的映射关系
    private Map<String, DynamicPermissionEntity> permissionEntityMap;

    public void setApplyPermissionsCallback(DynamicPermissionEmitter.ApplyPermissionsCallback applyPermissionsCallback) {
        this.applyPermissionsCallback = applyPermissionsCallback;

    }

    public static DynamicPermissionFragment newInstance() {
        return new DynamicPermissionFragment();
    }

    /**
     * 提交要申请的权限
     * 此方法会提取出未授权的权限与已授权的权限,支队未授权的权限进行申请
     *
     * @param permissions 权限数组
     */
    public void commitPermission(String... permissions) {
        try {
            permissionEntityMap = new HashMap<>();

            if (Build.VERSION.SDK_INT < 23) {
                //6.0 以下 无法检测到权限
                for (String permission : permissions) {
                    DynamicPermissionEntity dynamicPermissionEntity = new DynamicPermissionEntity();
                    dynamicPermissionEntity.setPermissionName(permission);
                    dynamicPermissionEntity.setPermissionState(DynamicPermissionEntity.PERMISSION_UN_HANDLE);
                    permissionEntityMap.put(permission, dynamicPermissionEntity);
                }
                if (applyPermissionsCallback != null) {
                    // callback 之前做一次检查
                    Map<String, DynamicPermissionEntity> checkPermissionResult = checkPermissionEntityAndRemoveNullEntity(permissionEntityMap);
                    if (checkPermissionResult != null && checkPermissionResult.size() != 0) {
                        applyPermissionsCallback.applyPermissionResult(checkPermissionResult);
                    }
                }
                return;
            }

            List<String> unGrantedPermissions = new ArrayList<>(); //未授权的权限列表
            for (String permission : permissions) {
                if (hasPermission(permission)) {
                    DynamicPermissionEntity dynamicPermissionEntity = new DynamicPermissionEntity();
                    dynamicPermissionEntity.setPermissionName(permission);
                    dynamicPermissionEntity.setPermissionState(DynamicPermissionEntity.PERMISSION_GRANTED);
                    permissionEntityMap.put(permission, dynamicPermissionEntity);
                } else {
                    unGrantedPermissions.add(permission);
                }
            }

            if (unGrantedPermissions.size() == 0) {
                if (applyPermissionsCallback != null) {
                    // callback 之前做一次检查
                    Map<String, DynamicPermissionEntity> checkPermissionResult = checkPermissionEntityAndRemoveNullEntity(permissionEntityMap);
                    if (checkPermissionResult != null && checkPermissionResult.size() != 0) {
                        applyPermissionsCallback.applyPermissionResult(checkPermissionResult);
                    }
                }
                return;
            }

            // 开始请求权限
            applyDynamicPermissions(unGrantedPermissions.toArray(new String[]{}));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param permission 权限
     * @return 是否拥有某个权限
     */
    public boolean hasPermission(String permission) {
        //ContextCompat这种方式检查权限在小米手机上会有问题,使用PermissionChecker 检查权限会正常
        //return ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED;
        return Build.VERSION.SDK_INT < 23 ||
                PermissionChecker.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED;
    }

    /**
     * 请求权限
     *
     * @param permissions 权限list
     */
    @TargetApi(23)
    private void applyDynamicPermissions(String... permissions) {
        requestPermissions(permissions, REQUEST_PERMISSION_CODE);
    }

    /**
     * 检查要请求的权限在manifest中是否注册
     *
     * @param permissions 权限列表
     */
    @SuppressLint("LongLogTag")
    public void checkRegisteredPermissionInManifest(String... permissions) {
        PackageManager pm = activity.getPackageManager();
        if (pm != null) {
            try {
                String[] requestedPermissions = pm.getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS).requestedPermissions;
                if (requestedPermissions != null) {
                    if (!Arrays.asList(requestedPermissions).containsAll(Arrays.asList(permissions))) {
                        throw new IllegalArgumentException("please register the permissions in manifest...");
                    }
                } else {
                    if (permissions.length != 0) {
                        throw new IllegalArgumentException("please register the permissions in manifest...");
                    }
                }
            } catch (PackageManager.NameNotFoundException e) {
                Log.e(TAG, "haveRegisteredPermissionInManifest", e);
            }
        }
    }

    /**
     * 是否勾选了不在提示
     *
     * @param permission 权限
     * @return true 勾选了不在提示, false没有勾选不在提示,只是拒绝了某个权限
     */
    private boolean isSelectedNoTips(@NonNull String permission) {
        return !ActivityCompat.shouldShowRequestPermissionRationale(activity, permission);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        activity = (Activity) context;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        try {
            if (activity == null || activity.isFinishing()) {
                // 页面关闭不处理结果
                return;
            }
            if (REQUEST_PERMISSION_CODE == requestCode && permissions.length == grantResults.length) {

                for (int i = 0; i < permissions.length; i++) {
                    String permission = permissions[i];
                    int grant = grantResults[i];
                    DynamicPermissionEntity dynamicPermissionEntity = new DynamicPermissionEntity();
                    dynamicPermissionEntity.setPermissionName(permission);
                    if (grant == PackageManager.PERMISSION_GRANTED) {
                        dynamicPermissionEntity.setPermissionState(DynamicPermissionEntity.PERMISSION_GRANTED);
                    } else {
                        if (isSelectedNoTips(permission)) {
                            dynamicPermissionEntity.setPermissionState(DynamicPermissionEntity.PERMISSION_DENIED_AND_SELECTED_NO_PROMPT);
                        } else {
                            dynamicPermissionEntity.setPermissionState(DynamicPermissionEntity.PERMISSION_DENIED);
                        }
                    }
                    if (permissionEntityMap != null) {
                        permissionEntityMap.put(permission, dynamicPermissionEntity);
                    }
                }
                if (applyPermissionsCallback != null) {
                    // callback 之前做一次检查
                    Map<String, DynamicPermissionEntity> checkPermissionResult = checkPermissionEntityAndRemoveNullEntity(permissionEntityMap);
                    if (checkPermissionResult != null && checkPermissionResult.size() != 0) {
                        applyPermissionsCallback.applyPermissionResult(checkPermissionResult);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * key 或者 value 如果有为空的 直接移除
     * 防止key 或 value为空,省区使用的地方在去判断
     *
     * @param permissionEntityMap 权限名称对应权限实体类的映射
     * @return 结果
     */
    private Map<String, DynamicPermissionEntity> checkPermissionEntityAndRemoveNullEntity(Map<String, DynamicPermissionEntity> permissionEntityMap) {
        try {
            if (permissionEntityMap != null && permissionEntityMap.size() != 0) {
                Iterator<Map.Entry<String, DynamicPermissionEntity>> iterator = permissionEntityMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, DynamicPermissionEntity> next = iterator.next();
                    String key = next.getKey();
                    DynamicPermissionEntity value = next.getValue();
                    if (TextUtils.isEmpty(key) || value == null) {
                        // TODO: 2018/12/1 有key 或 value 为空的情况,如果需要log 在这里输出
                        iterator.remove();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return permissionEntityMap;
    }

}

4.在清单中配置权限

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

5.调用

 private DynamicPermissionEmitter permissionEmitter;

 permissionEmitter.emitterPermission(new DynamicPermissionEmitter.ApplyPermissionsCallback() {
                    @Override
                    public void applyPermissionResult(Map<String, DynamicPermissionEntity> permissionEntityMap) {
                        DynamicPermissionEntity dynamicPermissionEntity = permissionEntityMap.get(Manifest.permission.WRITE_EXTERNAL_STORAGE);
                        if (dynamicPermissionEntity.isGranted()) {
                            Toast.makeText(MainActivity.this, "允许", Toast.LENGTH_LONG).show();
                        } else if (dynamicPermissionEntity.shouldShowRequestPermissionRational()) {
                            Toast.makeText(MainActivity.this, "勾选不在提示并且拒绝", Toast.LENGTH_LONG).show();
                        } else {
                            Toast.makeText(MainActivity.this, "拒绝", Toast.LENGTH_LONG).show();
                        }
                    }
                }, Manifest.permission.WRITE_EXTERNAL_STORAGE);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值