經過 PermissionUtil 對象做爲門面將庫暴露給使用模塊。主要設置了 AppCompatActivity 和 Fragment 中獲取權限的途徑。bash
public class PermissionUtil {
public static PermissionWrapper with(AppCompatActivity activity) {
return new PermissionWrapper(activity);
}
public static PermissionWrapper with(Fragment fragment) {
return new PermissionWrapper(fragment);
}
}
複製代碼
將有關權限的操做封裝成了 PermissionWrapper 對象。主要包括了判斷權限是否獲取,請求單個權限和請求多個權限的功能。app
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 進行比較返回結果。ide
調用方式:ui
boolean hasContactsPermission = PermissionUtil.with(this).isGranted(Manifest.permission.WRITE_CONTACTS);
複製代碼
由於涉及到請求權限,咱們將須要請求的權限封裝成 PermissionRequestWrapper。this
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() 方法發起,經過傳入的請求碼進行標示。spa
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 保存在一個集合中。由於有可能咱們會重複請求權限,因此須要判斷哪些權限已經請求。code
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 ,判斷是否進行權限請求。對象
與請求單個權限一樣。只是將單個權限封裝爲一個集合進行處理。rem
經過返回的 PermissionRequestWrapper 方法,能夠設置對應的回調方法。包括合理的,贊成的,拒絕的,獲取全部參數的方法。get
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);
}
複製代碼