From a9dbb35534fccfa53a0a8d73e437aaf71ced0abe Mon Sep 17 00:00:00 2001 From: Zhanty Date: Wed, 3 Jul 2019 11:37:00 +0800 Subject: [PATCH] optimize permission requester --- .../permission/AutoPermissionFragment.java | 13 +-- .../permission/AutoPermissionRequester.java | 74 ++++++++++++----- .../DefaultPermissionUIProvider.java | 2 +- .../base/permission/EasyPermissions.java | 10 +-- .../base/permission/PermissionCallback.java | 12 ++- ...terImpl.java => PermissionCallerImpl.java} | 4 +- .../base/permission/PermissionRequester.java | 79 ------------------- 7 files changed, 79 insertions(+), 115 deletions(-) rename lib_base/src/main/java/com/android/base/permission/{PermissionRequesterImpl.java => PermissionCallerImpl.java} (92%) delete mode 100644 lib_base/src/main/java/com/android/base/permission/PermissionRequester.java diff --git a/lib_base/src/main/java/com/android/base/permission/AutoPermissionFragment.java b/lib_base/src/main/java/com/android/base/permission/AutoPermissionFragment.java index 373c008..3fe478f 100644 --- a/lib_base/src/main/java/com/android/base/permission/AutoPermissionFragment.java +++ b/lib_base/src/main/java/com/android/base/permission/AutoPermissionFragment.java @@ -23,7 +23,7 @@ public class AutoPermissionFragment extends Fragment { private final Handler mHandler = new Handler(); private final Runnable mRunnable = this::startChecked; - private AutoPermissionFragmentCallback mRequesterReference; + private AutoPermissionFragmentCallback mCallback; private boolean mIsActivityReady = false; @Override @@ -47,7 +47,7 @@ public class AutoPermissionFragment extends Fragment { @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - Timber.d("onRequestPermissionsResult() called " + mRequesterReference); + Timber.d("onRequestPermissionsResult() called " + mCallback); AutoPermissionFragmentCallback callback = getCallback(); if (callback != null) { @@ -57,7 +57,7 @@ public class AutoPermissionFragment extends Fragment { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { - Timber.d("onActivityResult() called " + mRequesterReference); + Timber.d("onActivityResult() called " + mCallback); super.onActivityResult(requestCode, resultCode, data); AutoPermissionFragmentCallback callback = getCallback(); @@ -72,7 +72,7 @@ public class AutoPermissionFragment extends Fragment { } private void startChecked() { - Timber.d("startChecked() called " + mRequesterReference); + Timber.d("startChecked() called " + mCallback); if (mIsActivityReady) { AutoPermissionFragmentCallback callback = getCallback(); if (callback != null) { @@ -88,15 +88,16 @@ public class AutoPermissionFragment extends Fragment { public void onDestroy() { super.onDestroy(); mHandler.removeCallbacks(mRunnable); + mCallback = null; } void setRequester(AutoPermissionFragmentCallback requester) { Timber.d("setRequester() called with: requester = [" + requester + "]"); - mRequesterReference = requester; + mCallback = requester; } private AutoPermissionFragmentCallback getCallback() { - return mRequesterReference; + return mCallback; } interface AutoPermissionFragmentCallback { diff --git a/lib_base/src/main/java/com/android/base/permission/AutoPermissionRequester.java b/lib_base/src/main/java/com/android/base/permission/AutoPermissionRequester.java index 4e12b92..2ff9531 100644 --- a/lib_base/src/main/java/com/android/base/permission/AutoPermissionRequester.java +++ b/lib_base/src/main/java/com/android/base/permission/AutoPermissionRequester.java @@ -15,6 +15,7 @@ import java.util.Arrays; import timber.log.Timber; import static com.android.base.permission.PermissionCode.PERMISSION_REQUESTER_CODE; +import static com.android.base.permission.PermissionCode.REQUEST_PERMISSION_FOR_SETTING; /** *
@@ -42,18 +43,21 @@ public class AutoPermissionRequester {
 
     private OnAllPermissionGrantedListener mOnAllPermissionGrantedListener;
     private OnPermissionDeniedListener mOnPermissionDeniedListener;
+    private IPermissionUIProvider mPermissionUIProvider;
+
+    private ActFragWrapper mActFragWrapper;
 
     private PermissionCallback mPermissionCallback;
 
-    private IPermissionUIProvider mPermissionUIProvider;
-    private PermissionRequester mPermissionRequester;
+    private boolean mIsRequested;
 
     private AutoPermissionFragment.AutoPermissionFragmentCallback mAutoPermissionFragmentCallback;
+    private EasyPermissions.PermissionCaller mPermissionCaller;
 
     private AutoPermissionRequester(FragmentActivity activity, LifecycleOwner lifecycleOwner) {
         mActivity = activity;
         if (mActivity == null) {
-            throw new NullPointerException();
+            throw new NullPointerException("activity is null.");
         }
 
         DefaultLifecycleObserver observer = new DefaultLifecycleObserver() {
@@ -61,21 +65,24 @@ public class AutoPermissionRequester {
             public void onDestroy(@NonNull LifecycleOwner owner) {
                 mOnAllPermissionGrantedListener = null;
                 mOnPermissionDeniedListener = null;
+                mPermissionUIProvider = null;
+                mPermissionCallback.setDestroyed();
             }
         };
+
         lifecycleOwner.getLifecycle().addObserver(observer);
     }
 
-    public static AutoPermissionRequester with(Fragment fragment) {
+    public static AutoPermissionRequester with(@NonNull Fragment 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);
     }
 
-    public AutoPermissionRequester permission(String... permissions) {
-        if (permissions == null || permissions.length == 0) {
+    public AutoPermissionRequester permission(@NonNull String... permissions) {
+        if (permissions.length == 0) {
             throw new IllegalArgumentException();
         }
         mPerms = permissions;
@@ -108,6 +115,10 @@ public class AutoPermissionRequester {
     }
 
     public void request() {
+        if (mIsRequested) {
+            throw new UnsupportedOperationException("AutoPermissionRequester instance just can be used by once.");
+        }
+        mIsRequested = true;
         mPermissionCallback = new PermissionCallback(mOnPermissionDeniedListener, mOnAllPermissionGrantedListener);
         startRequest();
     }
@@ -118,15 +129,14 @@ public class AutoPermissionRequester {
 
         if (fragment == null) {
             fragment = AutoPermissionFragment.newInstance();
-
             supportFragmentManager.beginTransaction()
                     .add(fragment, AutoPermissionFragment.class.getName())
                     .commitNowAllowingStateLoss();
-
         }
 
         fragment.setRequester(getCallback());
-        mPermissionRequester = new PermissionRequester(ActFragWrapper.create(fragment), mPermissionCallback, mAskAgain, mShowTips, mPermissionUIProvider);
+
+        mActFragWrapper = ActFragWrapper.create(fragment);
 
         fragment.startRequest();
     }
@@ -137,24 +147,20 @@ public class AutoPermissionRequester {
                 @Override
                 public void onReady() {
                     Timber.d("onReady() called");
-                    if (mPermissionRequester != null) {
-                        mPermissionRequester.requestPermission(PERMISSION_REQUESTER_CODE, mPerms);
-                    }
+                    requestPermission(mPerms);
                 }
 
                 @Override
                 public void onActivityResult(int requestCode, int resultCode, Intent data) {
                     Timber.d("onActivityResult() called with: requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]");
-                    if (mPermissionRequester != null) {
-                        mPermissionRequester.onActivityResult(requestCode, resultCode, data);
-                    }
+                    AutoPermissionRequester.this.onActivityResult(requestCode, resultCode, data);
                 }
 
                 @Override
                 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) + "]");
-                    if (requestCode == PERMISSION_REQUESTER_CODE && mPermissionRequester != null) {
-                        mPermissionRequester.onRequestPermissionsResult(requestCode, permissions, grantResults);
+                    if (requestCode == PERMISSION_REQUESTER_CODE) {
+                        AutoPermissionRequester.this.onRequestPermissionsResult(requestCode, permissions, grantResults);
                     }
                 }
             };
@@ -162,4 +168,36 @@ public class AutoPermissionRequester {
         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();//所有权限被获取
+            }
+        }
+    }
+
 }
diff --git a/lib_base/src/main/java/com/android/base/permission/DefaultPermissionUIProvider.java b/lib_base/src/main/java/com/android/base/permission/DefaultPermissionUIProvider.java
index 6ddd97f..51f21a8 100644
--- a/lib_base/src/main/java/com/android/base/permission/DefaultPermissionUIProvider.java
+++ b/lib_base/src/main/java/com/android/base/permission/DefaultPermissionUIProvider.java
@@ -12,7 +12,6 @@ import android.text.style.ForegroundColorSpan;
 import com.android.base.R;
 import com.blankj.utilcode.util.AppUtils;
 import com.blankj.utilcode.util.ToastUtils;
-import com.yanzhenjie.permission.Permission;
 
 import java.util.Arrays;
 import java.util.List;
@@ -46,6 +45,7 @@ class DefaultPermissionUIProvider implements IPermissionUIProvider {
                 .setPositiveButton(R.string.Base_to_set_permission, onToSetPermissionListener)
                 .setNegativeButton(R.string.Base_Cancel, onCancelListener)
                 .create();
+
         dialog.show();
     }
 
diff --git a/lib_base/src/main/java/com/android/base/permission/EasyPermissions.java b/lib_base/src/main/java/com/android/base/permission/EasyPermissions.java
index 7455382..c89de2d 100644
--- a/lib_base/src/main/java/com/android/base/permission/EasyPermissions.java
+++ b/lib_base/src/main/java/com/android/base/permission/EasyPermissions.java
@@ -53,7 +53,7 @@ final class EasyPermissions {
         void onPermissionsDenied(int requestCode, List perms);
 
         /**
-         * @return PermissionCaller must is Fragment(app and support) or Activity
+         * @return PermissionCaller must be Fragment(app and support) or Activity
          */
         Object getRequester();
 
@@ -91,7 +91,6 @@ final class EasyPermissions {
         return true;
     }
 
-
     /**
      * 请求权限
      */
@@ -128,8 +127,7 @@ final class EasyPermissions {
     static String[] filter(Context context, String[] perms) {
         List permList = new ArrayList<>();
         for (String perm : perms) {
-            boolean hasPerm = (ContextCompat.checkSelfPermission(context, perm) ==
-                    PackageManager.PERMISSION_GRANTED);
+            boolean hasPerm = (ContextCompat.checkSelfPermission(context, perm) == PackageManager.PERMISSION_GRANTED);
             if (!hasPerm) {
                 permList.add(perm);
             }
@@ -199,8 +197,7 @@ final class EasyPermissions {
         } else if (permissionCaller.getRequester() instanceof Fragment) {
             return ((Fragment) permissionCaller.getRequester()).shouldShowRequestPermissionRationale(perm);
         } else
-            return permissionCaller.getRequester() instanceof android.app.Fragment
-                    && ((android.app.Fragment) permissionCaller.getRequester()).shouldShowRequestPermissionRationale(perm);
+            return permissionCaller.getRequester() instanceof android.app.Fragment && ((android.app.Fragment) permissionCaller.getRequester()).shouldShowRequestPermissionRationale(perm);
     }
 
     /**
@@ -216,4 +213,5 @@ final class EasyPermissions {
             ((android.app.Fragment) permissionCaller.getRequester()).requestPermissions(perms, requestCode);
         }
     }
+
 }
diff --git a/lib_base/src/main/java/com/android/base/permission/PermissionCallback.java b/lib_base/src/main/java/com/android/base/permission/PermissionCallback.java
index 5d7f5e0..2e7b8ff 100644
--- a/lib_base/src/main/java/com/android/base/permission/PermissionCallback.java
+++ b/lib_base/src/main/java/com/android/base/permission/PermissionCallback.java
@@ -1,9 +1,11 @@
-package com.android.base.permission;   // Callback
+package com.android.base.permission;
 
 import java.util.List;
 
 class PermissionCallback {
 
+    private boolean mIsDestroyed = false;
+
     private final OnPermissionDeniedListener mOnPermissionDeniedListener;
     private final OnAllPermissionGrantedListener mOnAllPermissionGrantedListener;
 
@@ -13,15 +15,19 @@ class PermissionCallback {
     }
 
     void onPermissionDenied(List strings) {
-        if (mOnPermissionDeniedListener != null) {
+        if (mOnPermissionDeniedListener != null && !mIsDestroyed) {
             mOnPermissionDeniedListener.onPermissionDenied(strings);
         }
     }
 
     void onAllPermissionGranted() {
-        if (mOnAllPermissionGrantedListener != null) {
+        if (mOnAllPermissionGrantedListener != null && !mIsDestroyed) {
             mOnAllPermissionGrantedListener.onAllPermissionGranted();
         }
     }
 
+    void setDestroyed() {
+        mIsDestroyed = true;
+    }
+
 }
\ No newline at end of file
diff --git a/lib_base/src/main/java/com/android/base/permission/PermissionRequesterImpl.java b/lib_base/src/main/java/com/android/base/permission/PermissionCallerImpl.java
similarity index 92%
rename from lib_base/src/main/java/com/android/base/permission/PermissionRequesterImpl.java
rename to lib_base/src/main/java/com/android/base/permission/PermissionCallerImpl.java
index 2943619..bff3ffb 100644
--- a/lib_base/src/main/java/com/android/base/permission/PermissionRequesterImpl.java
+++ b/lib_base/src/main/java/com/android/base/permission/PermissionCallerImpl.java
@@ -11,7 +11,7 @@ import timber.log.Timber;
 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 mShowTips;
@@ -20,7 +20,7 @@ class PermissionRequesterImpl implements EasyPermissions.PermissionCaller {
     private PermissionCallback mPermissionCallback;
     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;
         mContextWrapper = contextWrapper;
         mShouldAskAgain = shouldAskAgain;
diff --git a/lib_base/src/main/java/com/android/base/permission/PermissionRequester.java b/lib_base/src/main/java/com/android/base/permission/PermissionRequester.java
deleted file mode 100644
index 82beb45..0000000
--- a/lib_base/src/main/java/com/android/base/permission/PermissionRequester.java
+++ /dev/null
@@ -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;
-
-/**
- * 
- *      1:使用{@link #requestPermission(int, String...)}来申请权限,当所有的权限都通过时回调权限获取成功,否则回调权限获取失败。
- *      2:不要同时调用requestPermission方法多次!!!以保证一个完整的流程。
- * 获取权限流程,以申请相机权限为例:
- *          1先检查自身是否有相机权限
- *          2如果有我们的app已经有了相机权限,则可以直接使用相机相关功能了
- *          3如果没有权限我们就需要请求权限了,但是还需要处理不再询问的设置
- *              3.1如果shouldShowRequestPermissionRationale返回false,则说明接下来的对话框不包含”不再询问“选择框,我们可以直接申请权限
- *              3.2如果shouldShowRequestPermissionRationale返回true,我们最好先弹出一个对话框来说明我们需要权限来做什么,让用户来选择是否继续授予权限,如果用户允许继续授予权限则继续申请权限
- *          4不管权限是否授予给我们的App,都可以在onRequestPermissionsResult的回调中获取结果,我们再问一次
- * 
- * - * @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();//所有权限被获取 - } - } - } - -}