Android运行时权限处理

栏目: IOS · Android · 发布时间: 4年前

内容简介:通过 PermissionUtil 对象作为门面将库暴露给使用模块。主要设置了 AppCompatActivity 和 Fragment 中获取权限的途径。将有关权限的操作封装成了 PermissionWrapper 对象。主要包括了判断权限是否获取,请求单个权限和请求多个权限的功能。直接调用系统方法 ContextCompat.checkSelfPermission(),通过返回值与 PackageManager.PERMISSION_GRANTED 进行比较返回结果。

通过 PermissionUtil 对象作为门面将库暴露给使用模块。主要设置了 AppCompatActivity 和 Fragment 中获取权限的途径。

public class PermissionUtil {

    public static PermissionWrapper with(AppCompatActivity activity) {
        return new PermissionWrapper(activity);
    }
    
    public static PermissionWrapper with(Fragment fragment) {
        return new PermissionWrapper(fragment);
    }
}
复制代码

将有关权限的操作封装成了 PermissionWrapper 对象。主要包括了判断权限是否获取,请求单个权限和请求多个权限的功能。

public static class PermissionWrapper {
    private AppCompatActivity mActivity;
    private Fragment mFragment;

    PermissionWrapper(AppCompatActivity activity) {
        mActivity = activity;
    }

    PermissionWrapper(Fragment fragment) {
        mFragment = fragment;
    }

    public boolean isGranted(String permissionType) {
        int permissionCheck;
        if (mActivity != null) {
            permissionCheck = ContextCompat.checkSelfPermission(mActivity, permissionType);
        } else {
            permissionCheck = ContextCompat.checkSelfPermission(mFragment.getContext(), permissionType);
        }
        return permissionCheck == PackageManager.PERMISSION_GRANTED;
    }

    public PermissionRequestWrapper request(String permissionType) {
        if (mActivity != null) {
            return new PermissionRequestWrapper(mActivity, new String[]{permissionType});
        } else {
            return new PermissionRequestWrapper(mFragment, new String[]{permissionType});
        }
    }

    public PermissionRequestWrapper request(String ... permissionTypes) {
        if (mActivity != null) {
            return new PermissionRequestWrapper(mActivity, permissionTypes);
        } else {
            return new PermissionRequestWrapper(mFragment, permissionTypes);
        }
    }
}
复制代码
  • 判断权限是否获取

直接调用系统方法 ContextCompat.checkSelfPermission(),通过返回值与 PackageManager.PERMISSION_GRANTED 进行比较返回结果。

调用方式:

boolean hasContactsPermission = PermissionUtil.with(this).isGranted(Manifest.permission.WRITE_CONTACTS);
复制代码
  • 请求单个权限和请求多个权限的功能

因为涉及到请求权限,我们将需要请求的权限封装成 PermissionRequestWrapper。

public static class PermissionRequestWrapper {
    private static final String TAG = PermissionRequestWrapper.class.getSimpleName();
    private AppCompatActivity mActivity;
    private Fragment mFragment;
    private Func mDenyFunc;
    private Func mGrantFunc;
    private String[] mPermissionTypes;
    private List<SinglePermission> mPermissionsWeDontHave;
    private Func3 mRationalFunc;
    private int mRequestCode;
    private Func2 mResultFunc;

    public PermissionRequestWrapper(AppCompatActivity activity, String[] permissionTypes) {
        mActivity = activity;
        mPermissionTypes = permissionTypes;
    }

    public PermissionRequestWrapper(Fragment fragment, String[] permissionTypes) {
        mFragment = fragment;
        mPermissionTypes = permissionTypes;
    }

    public PermissionRequestWrapper requestCode(int reqCode) {
        mRequestCode = reqCode;
        int length = mPermissionTypes.length;
        mPermissionsWeDontHave = new ArrayList<>(length);
        for (String permissionType : mPermissionTypes) {
            mPermissionsWeDontHave.add(new SinglePermission(permissionType));
        }

        if (needToRequest()) {
            Log.i(TAG, "Asking for permission");
            if (mActivity != null) {
                ActivityCompat.requestPermissions(mActivity, mPermissionTypes, reqCode);
            } else {
                mFragment.requestPermissions(mPermissionTypes, reqCode);
            }
        } else {
            Log.i(TAG, "No need to ask for permission");
            if (mGrantFunc != null) {
                mGrantFunc.call();
            }
        }
        return this;
    }

    private boolean needToRequest() {
        List<SinglePermission> neededPermissions = new ArrayList<>(mPermissionsWeDontHave);
        for (int i = 0; i < mPermissionsWeDontHave.size(); i++) {
            SinglePermission perm = mPermissionsWeDontHave.get(i);
            int checkRes;
            if (mActivity != null) {
                checkRes = ContextCompat.checkSelfPermission(mActivity, perm.getPermissionName());
            } else {
                checkRes = ContextCompat.checkSelfPermission(mFragment.getContext(), perm.getPermissionName());
            }
            if (checkRes == PackageManager.PERMISSION_GRANTED) {
                neededPermissions.remove(perm);
            } else {
                boolean shouldShowRequestPermissionRationale;
                if (mActivity != null) {
                    shouldShowRequestPermissionRationale = ActivityCompat.shouldShowRequestPermissionRationale(mActivity, perm.getPermissionName());
                } else {
                    shouldShowRequestPermissionRationale = mFragment.shouldShowRequestPermissionRationale(perm.getPermissionName());
                }
                if (shouldShowRequestPermissionRationale) {
                    perm.setRationalNeeded(true);
                }
            }
        }
        mPermissionsWeDontHave = neededPermissions;
        mPermissionTypes = new String[mPermissionsWeDontHave.size()];
        for (int i = 0; i < mPermissionsWeDontHave.size(); i++) {
            mPermissionTypes[i] = mPermissionsWeDontHave.get(i).getPermissionName();
        }
        return mPermissionsWeDontHave.size() != 0;
    }

    public PermissionRequestWrapper onRational(Func3 rationalFunc) {
        mRationalFunc = rationalFunc;
        return this;
    }

    public PermissionRequestWrapper onAllGranted(Func grantFunc) {
        mGrantFunc = grantFunc;
        return this;
    }

    public PermissionRequestWrapper onAnyDenied(Func denyFunc) {
        mDenyFunc = denyFunc;
        return this;
    }

    public PermissionRequestWrapper onResult(Func2 resultFunc) {
        mResultFunc = resultFunc;
        return this;
    }

    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        if (mRequestCode == requestCode) {
            if (mResultFunc != null) {
                Log.i(TAG, "Calling Results Func");
                mResultFunc.call(requestCode, permissions, grantResults);
                return;
            }

            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                    if (mPermissionsWeDontHave.get(i).isRationalNeeded() && mRationalFunc != null) {
                        Log.i(TAG, "Calling Rational Func");
                        mRationalFunc.call(mPermissionsWeDontHave.get(i).getPermissionName());
                    } else if (mDenyFunc != null) {
                        Log.i(TAG, "Calling Deny Func");
                        mDenyFunc.call();
                    } else {
                        Log.e(TAG, "NUll DENY FUNCTIONS");
                    }

                    return;
                }
            }

            if (mGrantFunc != null) {
                Log.i(TAG, "Calling Grant Func");
                mGrantFunc.call();
            } else {
                Log.e(TAG, "NUll GRANT FUNCTIONS");
            }
        }
    }
}
复制代码
  • 请求单个权限

请求权限是通过 PermissionRequestWrapper.requestCode() 方法发起,通过传入的请求码进行标示。

public PermissionRequestWrapper requestCode(int reqCode) {
    mRequestCode = reqCode;
    int length = mPermissionTypes.length;
    mPermissionsWeDontHave = new ArrayList<>(length);
    for (String permissionType : mPermissionTypes) {
        mPermissionsWeDontHave.add(new SinglePermission(permissionType));
    }

    if (needToRequest()) {
        Log.i(TAG, "Asking for permission");
        if (mActivity != null) {
            ActivityCompat.requestPermissions(mActivity, mPermissionTypes, reqCode);
        } else {
            mFragment.requestPermissions(mPermissionTypes, reqCode);
        }
    } else {
        Log.i(TAG, "No need to ask for permission");
        if (mGrantFunc != null) {
            mGrantFunc.call();
        }
    }
    return this;
}
复制代码

mPermissionTypes 是通过构建 PermissionRequestWrapper 对象时传入的,代表了想要请求的所有权限。并将它封装为请求对象 SinglePermission 保存在一个集合中。因为有可能我们会重复请求权限,所以需要判断哪些权限已经请求。

private boolean needToRequest() {
    List<SinglePermission> neededPermissions = new ArrayList<>(mPermissionsWeDontHave);
    for (int i = 0; i < mPermissionsWeDontHave.size(); i++) {
        SinglePermission perm = mPermissionsWeDontHave.get(i);
        int checkRes;
        if (mActivity != null) {
            checkRes = ContextCompat.checkSelfPermission(mActivity, perm.getPermissionName());
        } else {
            checkRes = ContextCompat.checkSelfPermission(mFragment.getContext(), perm.getPermissionName());
        }
        if (checkRes == PackageManager.PERMISSION_GRANTED) {
            neededPermissions.remove(perm);
        } else {
            boolean shouldShowRequestPermissionRationale;
            if (mActivity != null) {
                shouldShowRequestPermissionRationale = ActivityCompat.shouldShowRequestPermissionRationale(mActivity, perm.getPermissionName());
            } else {
                shouldShowRequestPermissionRationale = mFragment.shouldShowRequestPermissionRationale(perm.getPermissionName());
            }
            if (shouldShowRequestPermissionRationale) {
                perm.setRationalNeeded(true);
            }
        }
    }
    mPermissionsWeDontHave = neededPermissions;
    mPermissionTypes = new String[mPermissionsWeDontHave.size()];
    for (int i = 0; i < mPermissionsWeDontHave.size(); i++) {
        mPermissionTypes[i] = mPermissionsWeDontHave.get(i).getPermissionName();
    }
    return mPermissionsWeDontHave.size() != 0;
}
复制代码

在方法中会遍历所有请求的权限,然后通过系统方法 ContextCompat.checkSelfPermission() 判断是否获取过。获取过则从集合中移除,没有获取过则跳过。最后通过集合中的权限请求数是否为 0 ,判断是否进行权限请求。

  • 请求多个权限

与请求单个权限同样。只是将单个权限封装为一个集合进行处理。

方法回调

通过返回的 PermissionRequestWrapper 方法,可以设置对应的回调方法。包括合理的,同意的,拒绝的,获取所有参数的方法。

public PermissionRequestWrapper onRational(Func3 rationalFunc) {
    mRationalFunc = rationalFunc;
    return this;
}

public PermissionRequestWrapper onAllGranted(Func grantFunc) {
    mGrantFunc = grantFunc;
    return this;
}

public PermissionRequestWrapper onAnyDenied(Func denyFunc) {
    mDenyFunc = denyFunc;
    return this;
}

public PermissionRequestWrapper onResult(Func2 resultFunc) {
    mResultFunc = resultFunc;
    return this;
}

public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    if (mRequestCode == requestCode) {
        if (mResultFunc != null) {
            Log.i(TAG, "Calling Results Func");
            mResultFunc.call(requestCode, permissions, grantResults);
            return;
        }

        for (int i = 0; i < permissions.length; i++) {
            if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                if (mPermissionsWeDontHave.get(i).isRationalNeeded() && mRationalFunc != null) {
                    Log.i(TAG, "Calling Rational Func");
                    mRationalFunc.call(mPermissionsWeDontHave.get(i).getPermissionName());
                } else if (mDenyFunc != null) {
                    Log.i(TAG, "Calling Deny Func");
                    mDenyFunc.call();
                } else {
                    Log.e(TAG, "NUll DENY FUNCTIONS");
                }

                return;
            }
        }

        if (mGrantFunc != null) {
            Log.i(TAG, "Calling Grant Func");
            mGrantFunc.call();
        } else {
            Log.e(TAG, "NUll GRANT FUNCTIONS");
        }
    }
}
复制代码

然后在 Activity 和 Fragment 的 onRequestPermissionsResult() 方法中进行调用 PermissionRequestWrapper 的 onRequestPermissionsResult() 方法。

@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
复制代码

以上所述就是小编给大家介绍的《Android运行时权限处理》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序设计语言理论基础

程序设计语言理论基础

米切尔 / 电子工业出版社 / 2006-11 / 68.00元

本书提出了一个框架,用于分析程序设计语言的语法、操作和语义性质,该框架基于称为类型化λ演算的数学系统。λ演算的主要特色是对于函数和其他可计算的值的一种记法,以及一个等式逻辑和用于表达式求值的一组规则。本书中最简单的系统是称为泛代数的一个等式系统,它可以用来公理化和分析通常用于程序设计的许多数据类型。可作为理论计算机科学、软件系统和数学专业的大学本科高年级或者研究生初始学习阶段的教材,同时也适合用于......一起来看看 《程序设计语言理论基础》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具