Android运行时权限处理

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

内容简介:通过 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运行时权限处理》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Natural Language Processing with Python

Natural Language Processing with Python

Steven Bird、Ewan Klein、Edward Loper / O'Reilly Media / 2009-7-10 / USD 44.99

This book offers a highly accessible introduction to Natural Language Processing, the field that underpins a variety of language technologies, ranging from predictive text and email filtering to autom......一起来看看 《Natural Language Processing with Python》 这本书的介绍吧!

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

html转js在线工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具