optimize permission requester

androidx
Zhanty 5 years ago
parent 16c172345d
commit a9dbb35534
  1. 13
      lib_base/src/main/java/com/android/base/permission/AutoPermissionFragment.java
  2. 74
      lib_base/src/main/java/com/android/base/permission/AutoPermissionRequester.java
  3. 2
      lib_base/src/main/java/com/android/base/permission/DefaultPermissionUIProvider.java
  4. 10
      lib_base/src/main/java/com/android/base/permission/EasyPermissions.java
  5. 12
      lib_base/src/main/java/com/android/base/permission/PermissionCallback.java
  6. 4
      lib_base/src/main/java/com/android/base/permission/PermissionCallerImpl.java
  7. 79
      lib_base/src/main/java/com/android/base/permission/PermissionRequester.java

@ -23,7 +23,7 @@ public class AutoPermissionFragment extends Fragment {
private final Handler mHandler = new Handler(); private final Handler mHandler = new Handler();
private final Runnable mRunnable = this::startChecked; private final Runnable mRunnable = this::startChecked;
private AutoPermissionFragmentCallback mRequesterReference; private AutoPermissionFragmentCallback mCallback;
private boolean mIsActivityReady = false; private boolean mIsActivityReady = false;
@Override @Override
@ -47,7 +47,7 @@ public class AutoPermissionFragment extends Fragment {
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Timber.d("onRequestPermissionsResult() called " + mRequesterReference); Timber.d("onRequestPermissionsResult() called " + mCallback);
AutoPermissionFragmentCallback callback = getCallback(); AutoPermissionFragmentCallback callback = getCallback();
if (callback != null) { if (callback != null) {
@ -57,7 +57,7 @@ public class AutoPermissionFragment extends Fragment {
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
Timber.d("onActivityResult() called " + mRequesterReference); Timber.d("onActivityResult() called " + mCallback);
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
AutoPermissionFragmentCallback callback = getCallback(); AutoPermissionFragmentCallback callback = getCallback();
@ -72,7 +72,7 @@ public class AutoPermissionFragment extends Fragment {
} }
private void startChecked() { private void startChecked() {
Timber.d("startChecked() called " + mRequesterReference); Timber.d("startChecked() called " + mCallback);
if (mIsActivityReady) { if (mIsActivityReady) {
AutoPermissionFragmentCallback callback = getCallback(); AutoPermissionFragmentCallback callback = getCallback();
if (callback != null) { if (callback != null) {
@ -88,15 +88,16 @@ public class AutoPermissionFragment extends Fragment {
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
mHandler.removeCallbacks(mRunnable); mHandler.removeCallbacks(mRunnable);
mCallback = null;
} }
void setRequester(AutoPermissionFragmentCallback requester) { void setRequester(AutoPermissionFragmentCallback requester) {
Timber.d("setRequester() called with: requester = [" + requester + "]"); Timber.d("setRequester() called with: requester = [" + requester + "]");
mRequesterReference = requester; mCallback = requester;
} }
private AutoPermissionFragmentCallback getCallback() { private AutoPermissionFragmentCallback getCallback() {
return mRequesterReference; return mCallback;
} }
interface AutoPermissionFragmentCallback { interface AutoPermissionFragmentCallback {

@ -15,6 +15,7 @@ import java.util.Arrays;
import timber.log.Timber; import timber.log.Timber;
import static com.android.base.permission.PermissionCode.PERMISSION_REQUESTER_CODE; import static com.android.base.permission.PermissionCode.PERMISSION_REQUESTER_CODE;
import static com.android.base.permission.PermissionCode.REQUEST_PERMISSION_FOR_SETTING;
/** /**
* <pre> * <pre>
@ -42,18 +43,21 @@ public class AutoPermissionRequester {
private OnAllPermissionGrantedListener mOnAllPermissionGrantedListener; private OnAllPermissionGrantedListener mOnAllPermissionGrantedListener;
private OnPermissionDeniedListener mOnPermissionDeniedListener; private OnPermissionDeniedListener mOnPermissionDeniedListener;
private IPermissionUIProvider mPermissionUIProvider;
private ActFragWrapper mActFragWrapper;
private PermissionCallback mPermissionCallback; private PermissionCallback mPermissionCallback;
private IPermissionUIProvider mPermissionUIProvider; private boolean mIsRequested;
private PermissionRequester mPermissionRequester;
private AutoPermissionFragment.AutoPermissionFragmentCallback mAutoPermissionFragmentCallback; private AutoPermissionFragment.AutoPermissionFragmentCallback mAutoPermissionFragmentCallback;
private EasyPermissions.PermissionCaller mPermissionCaller;
private AutoPermissionRequester(FragmentActivity activity, LifecycleOwner lifecycleOwner) { private AutoPermissionRequester(FragmentActivity activity, LifecycleOwner lifecycleOwner) {
mActivity = activity; mActivity = activity;
if (mActivity == null) { if (mActivity == null) {
throw new NullPointerException(); throw new NullPointerException("activity is null.");
} }
DefaultLifecycleObserver observer = new DefaultLifecycleObserver() { DefaultLifecycleObserver observer = new DefaultLifecycleObserver() {
@ -61,21 +65,24 @@ public class AutoPermissionRequester {
public void onDestroy(@NonNull LifecycleOwner owner) { public void onDestroy(@NonNull LifecycleOwner owner) {
mOnAllPermissionGrantedListener = null; mOnAllPermissionGrantedListener = null;
mOnPermissionDeniedListener = null; mOnPermissionDeniedListener = null;
mPermissionUIProvider = null;
mPermissionCallback.setDestroyed();
} }
}; };
lifecycleOwner.getLifecycle().addObserver(observer); lifecycleOwner.getLifecycle().addObserver(observer);
} }
public static AutoPermissionRequester with(Fragment fragment) { public static AutoPermissionRequester with(@NonNull Fragment fragment) {
return new AutoPermissionRequester(fragment.getActivity(), fragment); return new AutoPermissionRequester(fragment.getActivity(), fragment);
} }
public static AutoPermissionRequester with(FragmentActivity activity) { public static AutoPermissionRequester with(@NonNull FragmentActivity activity) {
return new AutoPermissionRequester(activity, activity); return new AutoPermissionRequester(activity, activity);
} }
public AutoPermissionRequester permission(String... permissions) { public AutoPermissionRequester permission(@NonNull String... permissions) {
if (permissions == null || permissions.length == 0) { if (permissions.length == 0) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
mPerms = permissions; mPerms = permissions;
@ -108,6 +115,10 @@ public class AutoPermissionRequester {
} }
public void request() { public void request() {
if (mIsRequested) {
throw new UnsupportedOperationException("AutoPermissionRequester instance just can be used by once.");
}
mIsRequested = true;
mPermissionCallback = new PermissionCallback(mOnPermissionDeniedListener, mOnAllPermissionGrantedListener); mPermissionCallback = new PermissionCallback(mOnPermissionDeniedListener, mOnAllPermissionGrantedListener);
startRequest(); startRequest();
} }
@ -118,15 +129,14 @@ public class AutoPermissionRequester {
if (fragment == null) { if (fragment == null) {
fragment = AutoPermissionFragment.newInstance(); fragment = AutoPermissionFragment.newInstance();
supportFragmentManager.beginTransaction() supportFragmentManager.beginTransaction()
.add(fragment, AutoPermissionFragment.class.getName()) .add(fragment, AutoPermissionFragment.class.getName())
.commitNowAllowingStateLoss(); .commitNowAllowingStateLoss();
} }
fragment.setRequester(getCallback()); fragment.setRequester(getCallback());
mPermissionRequester = new PermissionRequester(ActFragWrapper.create(fragment), mPermissionCallback, mAskAgain, mShowTips, mPermissionUIProvider);
mActFragWrapper = ActFragWrapper.create(fragment);
fragment.startRequest(); fragment.startRequest();
} }
@ -137,24 +147,20 @@ public class AutoPermissionRequester {
@Override @Override
public void onReady() { public void onReady() {
Timber.d("onReady() called"); Timber.d("onReady() called");
if (mPermissionRequester != null) { requestPermission(mPerms);
mPermissionRequester.requestPermission(PERMISSION_REQUESTER_CODE, mPerms);
}
} }
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
Timber.d("onActivityResult() called with: requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]"); Timber.d("onActivityResult() called with: requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]");
if (mPermissionRequester != null) { AutoPermissionRequester.this.onActivityResult(requestCode, resultCode, data);
mPermissionRequester.onActivityResult(requestCode, resultCode, data);
}
} }
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Timber.d("onRequestPermissionsResult() called with: requestCode = [" + requestCode + "], permissions = [" + Arrays.toString(permissions) + "], grantResults = [" + Arrays.toString(grantResults) + "]"); Timber.d("onRequestPermissionsResult() called with: requestCode = [" + requestCode + "], permissions = [" + Arrays.toString(permissions) + "], grantResults = [" + Arrays.toString(grantResults) + "]");
if (requestCode == PERMISSION_REQUESTER_CODE && mPermissionRequester != null) { if (requestCode == PERMISSION_REQUESTER_CODE) {
mPermissionRequester.onRequestPermissionsResult(requestCode, permissions, grantResults); AutoPermissionRequester.this.onRequestPermissionsResult(requestCode, permissions, grantResults);
} }
} }
}; };
@ -162,4 +168,36 @@ public class AutoPermissionRequester {
return mAutoPermissionFragmentCallback; return mAutoPermissionFragmentCallback;
} }
private EasyPermissions.PermissionCaller getPermissionCaller() {
if (mPermissionCaller == null) {
mPermissionCaller = new PermissionCallerImpl(mPermissionCallback, mActFragWrapper, mAskAgain, mShowTips, mPermissionUIProvider);
}
return mPermissionCaller;
}
private void requestPermission(String... perms) {
mPerms = perms;
EasyPermissions.requestPermissions(getPermissionCaller(), PermissionCode.PERMISSION_REQUESTER_CODE, mPerms);
}
private void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, getPermissionCaller());
}
private void onActivityResult(int requestCode, @SuppressWarnings("unused") int resultCode, @SuppressWarnings("unused") Intent data) {
if (requestCode == REQUEST_PERMISSION_FOR_SETTING) {//申请权限
if (!EasyPermissions.hasPermissions(mActFragWrapper.getContext(), mPerms)) {//Setting界面回来之后,没有授予权限
String[] filter = EasyPermissions.filter(mActFragWrapper.getContext(), mPerms);
mPermissionCallback.onPermissionDenied(Arrays.asList(filter));//权限被拒绝
if (mShowTips) {
getPermissionCaller().getPermissionUIProvider().showPermissionDeniedTip(mActFragWrapper.getContext(), filter);
}
} else {
mPermissionCallback.onAllPermissionGranted();//所有权限被获取
}
}
}
} }

@ -12,7 +12,6 @@ import android.text.style.ForegroundColorSpan;
import com.android.base.R; import com.android.base.R;
import com.blankj.utilcode.util.AppUtils; import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.ToastUtils; import com.blankj.utilcode.util.ToastUtils;
import com.yanzhenjie.permission.Permission;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -46,6 +45,7 @@ class DefaultPermissionUIProvider implements IPermissionUIProvider {
.setPositiveButton(R.string.Base_to_set_permission, onToSetPermissionListener) .setPositiveButton(R.string.Base_to_set_permission, onToSetPermissionListener)
.setNegativeButton(R.string.Base_Cancel, onCancelListener) .setNegativeButton(R.string.Base_Cancel, onCancelListener)
.create(); .create();
dialog.show(); dialog.show();
} }

@ -53,7 +53,7 @@ final class EasyPermissions {
void onPermissionsDenied(int requestCode, List<String> perms); void onPermissionsDenied(int requestCode, List<String> perms);
/** /**
* @return PermissionCaller must is Fragment(app and support) or Activity * @return PermissionCaller must be Fragment(app and support) or Activity
*/ */
Object getRequester(); Object getRequester();
@ -91,7 +91,6 @@ final class EasyPermissions {
return true; return true;
} }
/** /**
* 请求权限 * 请求权限
*/ */
@ -128,8 +127,7 @@ final class EasyPermissions {
static String[] filter(Context context, String[] perms) { static String[] filter(Context context, String[] perms) {
List<String> permList = new ArrayList<>(); List<String> permList = new ArrayList<>();
for (String perm : perms) { for (String perm : perms) {
boolean hasPerm = (ContextCompat.checkSelfPermission(context, perm) == boolean hasPerm = (ContextCompat.checkSelfPermission(context, perm) == PackageManager.PERMISSION_GRANTED);
PackageManager.PERMISSION_GRANTED);
if (!hasPerm) { if (!hasPerm) {
permList.add(perm); permList.add(perm);
} }
@ -199,8 +197,7 @@ final class EasyPermissions {
} else if (permissionCaller.getRequester() instanceof Fragment) { } else if (permissionCaller.getRequester() instanceof Fragment) {
return ((Fragment) permissionCaller.getRequester()).shouldShowRequestPermissionRationale(perm); return ((Fragment) permissionCaller.getRequester()).shouldShowRequestPermissionRationale(perm);
} else } else
return permissionCaller.getRequester() instanceof android.app.Fragment return permissionCaller.getRequester() instanceof android.app.Fragment && ((android.app.Fragment) permissionCaller.getRequester()).shouldShowRequestPermissionRationale(perm);
&& ((android.app.Fragment) permissionCaller.getRequester()).shouldShowRequestPermissionRationale(perm);
} }
/** /**
@ -216,4 +213,5 @@ final class EasyPermissions {
((android.app.Fragment) permissionCaller.getRequester()).requestPermissions(perms, requestCode); ((android.app.Fragment) permissionCaller.getRequester()).requestPermissions(perms, requestCode);
} }
} }
} }

@ -1,9 +1,11 @@
package com.android.base.permission; // Callback package com.android.base.permission;
import java.util.List; import java.util.List;
class PermissionCallback { class PermissionCallback {
private boolean mIsDestroyed = false;
private final OnPermissionDeniedListener mOnPermissionDeniedListener; private final OnPermissionDeniedListener mOnPermissionDeniedListener;
private final OnAllPermissionGrantedListener mOnAllPermissionGrantedListener; private final OnAllPermissionGrantedListener mOnAllPermissionGrantedListener;
@ -13,15 +15,19 @@ class PermissionCallback {
} }
void onPermissionDenied(List<String> strings) { void onPermissionDenied(List<String> strings) {
if (mOnPermissionDeniedListener != null) { if (mOnPermissionDeniedListener != null && !mIsDestroyed) {
mOnPermissionDeniedListener.onPermissionDenied(strings); mOnPermissionDeniedListener.onPermissionDenied(strings);
} }
} }
void onAllPermissionGranted() { void onAllPermissionGranted() {
if (mOnAllPermissionGrantedListener != null) { if (mOnAllPermissionGrantedListener != null && !mIsDestroyed) {
mOnAllPermissionGrantedListener.onAllPermissionGranted(); mOnAllPermissionGrantedListener.onAllPermissionGranted();
} }
} }
void setDestroyed() {
mIsDestroyed = true;
}
} }

@ -11,7 +11,7 @@ import timber.log.Timber;
import static com.android.base.permission.PermissionCode.REQUEST_PERMISSION_FOR_SETTING; import static com.android.base.permission.PermissionCode.REQUEST_PERMISSION_FOR_SETTING;
class PermissionRequesterImpl implements EasyPermissions.PermissionCaller { class PermissionCallerImpl implements EasyPermissions.PermissionCaller {
private final boolean mShouldAskAgain; private final boolean mShouldAskAgain;
private final boolean mShowTips; private final boolean mShowTips;
@ -20,7 +20,7 @@ class PermissionRequesterImpl implements EasyPermissions.PermissionCaller {
private PermissionCallback mPermissionCallback; private PermissionCallback mPermissionCallback;
private IPermissionUIProvider mIPermissionUIProvider; private IPermissionUIProvider mIPermissionUIProvider;
PermissionRequesterImpl(PermissionCallback permissionCallback, ActFragWrapper contextWrapper, boolean shouldAskAgain, boolean showTips, IPermissionUIProvider iPermissionUIProvider) { PermissionCallerImpl(PermissionCallback permissionCallback, ActFragWrapper contextWrapper, boolean shouldAskAgain, boolean showTips, IPermissionUIProvider iPermissionUIProvider) {
mPermissionCallback = permissionCallback; mPermissionCallback = permissionCallback;
mContextWrapper = contextWrapper; mContextWrapper = contextWrapper;
mShouldAskAgain = shouldAskAgain; mShouldAskAgain = shouldAskAgain;

@ -1,79 +0,0 @@
package com.android.base.permission;
import android.content.Intent;
import android.support.annotation.NonNull;
import com.android.base.utils.android.ActFragWrapper;
import java.util.Arrays;
import static com.android.base.permission.PermissionCode.REQUEST_PERMISSION_FOR_SETTING;
/**
* <pre>
* 1:使用{@link #requestPermission(int, String...)}来申请权限当所有的权限都通过时回调权限获取成功否则回调权限获取失败
* 2:不要同时调用requestPermission方法多次以保证一个完整的流程
* 获取权限流程,以申请相机权限为例
* 1先检查自身是否有相机权限
* 2如果有我们的app已经有了相机权限则可以直接使用相机相关功能了
* 3如果没有权限我们就需要请求权限了但是还需要处理不再询问的设置
* &nbsp; 3.1如果shouldShowRequestPermissionRationale返回false则说明接下来的对话框不包含不再询问选择框我们可以直接申请权限
* &nbsp; 3.2如果shouldShowRequestPermissionRationale返回true我们最好先弹出一个对话框来说明我们需要权限来做什么让用户来选择是否继续授予权限如果用户允许继续授予权限则继续申请权限
* 4不管权限是否授予给我们的App都可以在onRequestPermissionsResult的回调中获取结果我们再问一次
* </pre>
*
* @author Ztiany
* Email: 1169654504@qq.com
* Date : 2017-01-11 15:09
*/
class PermissionRequester {
private final ActFragWrapper mActFragWrapper;
private String[] mPerms;
private PermissionCallback mPermissionCallback;
private EasyPermissions.PermissionCaller mPermissionCaller;
private final boolean mAskAgain;
private final boolean mShowTips;
private final IPermissionUIProvider mPermissionUIProvider;
PermissionRequester(ActFragWrapper actFragWrapper, PermissionCallback permissionCallback, boolean askAgain, boolean showTips, IPermissionUIProvider permissionUIProvider) {
mPermissionCallback = permissionCallback;
mActFragWrapper = actFragWrapper;
mAskAgain = askAgain;
mShowTips = showTips;
mPermissionUIProvider = permissionUIProvider;
}
private EasyPermissions.PermissionCaller getPermissionCaller() {
if (mPermissionCaller == null) {
mPermissionCaller = new PermissionRequesterImpl(mPermissionCallback, mActFragWrapper, mAskAgain, mShowTips,mPermissionUIProvider);
}
return mPermissionCaller;
}
void requestPermission(int requestCode, String... perms) {
mPerms = perms;
EasyPermissions.requestPermissions(getPermissionCaller(), requestCode, mPerms);
}
void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, getPermissionCaller());
}
void onActivityResult(int requestCode, @SuppressWarnings("unused") int resultCode, @SuppressWarnings("unused") Intent data) {
if (requestCode == REQUEST_PERMISSION_FOR_SETTING) {//申请权限
if (!EasyPermissions.hasPermissions(mActFragWrapper.getContext(), mPerms)) {//Setting界面回来之后,没有授予权限
String[] filter = EasyPermissions.filter(mActFragWrapper.getContext(), mPerms);
mPermissionCallback.onPermissionDenied(Arrays.asList(filter));//权限被拒绝
if (mShowTips) {
mPermissionCaller.getPermissionUIProvider().showPermissionDeniedTip(mActFragWrapper.getContext(), filter);
}
} else {
mPermissionCallback.onAllPermissionGranted();//所有权限被获取
}
}
}
}
Loading…
Cancel
Save