permission);
206 | }
207 | }
208 |
--------------------------------------------------------------------------------
/policylib/src/main/java/com/db/policylib/receiver/DownLoadReceiver.java:
--------------------------------------------------------------------------------
1 | package com.db.policylib.receiver;
2 |
3 | import android.app.DownloadManager;
4 | import android.content.BroadcastReceiver;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.database.Cursor;
8 | import android.net.Uri;
9 | import android.os.Build;
10 | import android.widget.Toast;
11 |
12 | import androidx.core.content.FileProvider;
13 |
14 | import com.db.policylib.UpdateUtils;
15 |
16 | import java.io.File;
17 |
18 | public class DownLoadReceiver extends BroadcastReceiver {
19 | private long id = 0;
20 | private DownloadManager manager;
21 |
22 | @Override
23 | public void onReceive(Context context, Intent intent) {
24 | try {
25 | id = UpdateUtils.getInstance().getDownloadId(context);
26 | installFile(context);
27 | } catch (Exception e) {
28 | e.printStackTrace();
29 | }
30 | }
31 |
32 | private void installFile(final Context context) {
33 | DownloadManager.Query query = new DownloadManager.Query();
34 | query.setFilterById(id);
35 | manager = (DownloadManager) context.getSystemService(
36 | Context.DOWNLOAD_SERVICE);
37 | Cursor cursor = manager.query(query);
38 | if (cursor.moveToFirst()) {
39 | int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
40 | switch (status) {
41 | //下载完成
42 | case DownloadManager.STATUS_SUCCESSFUL:
43 | //下载完成安装APK
44 | installAPK(context);
45 | cursor.close();
46 | break;
47 | //下载失败
48 | case DownloadManager.STATUS_FAILED:
49 | Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show();
50 | cursor.close();
51 | context.unregisterReceiver(this);
52 | break;
53 | }
54 | }
55 | }
56 |
57 | private void installAPK(Context context) {
58 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
59 | File fileLocation = new File(context.getExternalFilesDir(null).getPath() + "/app.apk");
60 | Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileProvider", fileLocation);
61 | Intent installIntent = new Intent(Intent.ACTION_VIEW);
62 | installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
63 | installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
64 | installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
65 | context.startActivity(installIntent);
66 | } else {
67 | File fileLocation = new File(context.getExternalFilesDir(null).getPath() + "/app.apk");
68 | Intent installIntent = new Intent(Intent.ACTION_VIEW);
69 | installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
70 | installIntent.setDataAndType(Uri.fromFile(fileLocation),
71 | "application/vnd.android.package-archive");
72 | context.startActivity(installIntent);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/AfterPermissionGranted.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pub.devrel.easypermissions;
17 |
18 | import java.lang.annotation.ElementType;
19 | import java.lang.annotation.Retention;
20 | import java.lang.annotation.RetentionPolicy;
21 | import java.lang.annotation.Target;
22 |
23 | @Retention(RetentionPolicy.RUNTIME)
24 | @Target(ElementType.METHOD)
25 | public @interface AfterPermissionGranted {
26 |
27 | int value();
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/AppSettingsDialog.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.content.DialogInterface;
7 | import android.content.Intent;
8 | import android.os.Parcel;
9 | import android.os.Parcelable;
10 | import android.text.TextUtils;
11 |
12 | import androidx.annotation.NonNull;
13 | import androidx.annotation.Nullable;
14 | import androidx.annotation.RestrictTo;
15 | import androidx.annotation.StringRes;
16 | import androidx.annotation.StyleRes;
17 | import androidx.appcompat.app.AlertDialog;
18 | import androidx.fragment.app.Fragment;
19 |
20 | import com.db.policylib.PermissionPolicy;
21 | import com.db.policylib.Policy;
22 | import com.db.policylib.R;
23 |
24 | import java.util.List;
25 |
26 | /**
27 | * Dialog to prompt the user to go to the app's settings screen and enable permissions. If the user
28 | * clicks 'OK' on the dialog, they are sent to the settings screen. The result is returned to the
29 | * Activity via {@link Activity#(int, int, Intent)}.
30 | *
31 | * Use the {@link Builder} to create and display a dialog.
32 | */
33 | public class AppSettingsDialog implements Parcelable, Policy.PolicyClick {
34 | public static final int DEFAULT_SETTINGS_REQ_CODE = 16061;
35 |
36 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
37 | public static final Creator CREATOR = new Creator() {
38 | @Override
39 | public AppSettingsDialog createFromParcel(Parcel in) {
40 | return new AppSettingsDialog(in);
41 | }
42 |
43 | @Override
44 | public AppSettingsDialog[] newArray(int size) {
45 | return new AppSettingsDialog[size];
46 | }
47 | };
48 |
49 | static final String EXTRA_APP_SETTINGS = "extra_app_settings";
50 |
51 | @StyleRes
52 | private final int mThemeResId;
53 | private final String mRationale;
54 | private final String mTitle;
55 | private final String mPositiveButtonText;
56 | private final String mNegativeButtonText;
57 | private final int mRequestCode;
58 | private final int mIntentFlags;
59 |
60 | private Object mActivityOrFragment;
61 | private Context mContext;
62 |
63 | private AppSettingsDialog(Parcel in) {
64 | mThemeResId = in.readInt();
65 | mRationale = in.readString();
66 | mTitle = in.readString();
67 | mPositiveButtonText = in.readString();
68 | mNegativeButtonText = in.readString();
69 | mRequestCode = in.readInt();
70 | mIntentFlags = in.readInt();
71 | }
72 |
73 | private AppSettingsDialog(@NonNull final Object activityOrFragment,
74 | @StyleRes int themeResId,
75 | @Nullable String rationale,
76 | @Nullable String title,
77 | @Nullable String positiveButtonText,
78 | @Nullable String negativeButtonText,
79 | int requestCode,
80 | int intentFlags) {
81 | setActivityOrFragment(activityOrFragment);
82 | mThemeResId = themeResId;
83 | mRationale = rationale;
84 | mTitle = title;
85 | mPositiveButtonText = positiveButtonText;
86 | mNegativeButtonText = negativeButtonText;
87 | mRequestCode = requestCode;
88 | mIntentFlags = intentFlags;
89 | }
90 |
91 | static AppSettingsDialog fromIntent(Intent intent, Activity activity) {
92 | AppSettingsDialog dialog = intent.getParcelableExtra(AppSettingsDialog.EXTRA_APP_SETTINGS);
93 | dialog.setActivityOrFragment(activity);
94 | return dialog;
95 | }
96 |
97 | private void setActivityOrFragment(Object activityOrFragment) {
98 | mActivityOrFragment = activityOrFragment;
99 |
100 | if (activityOrFragment instanceof Activity) {
101 | mContext = (Activity) activityOrFragment;
102 | } else if (activityOrFragment instanceof Fragment) {
103 | mContext = ((Fragment) activityOrFragment).getContext();
104 | } else {
105 | throw new IllegalStateException("Unknown object: " + activityOrFragment);
106 | }
107 | }
108 |
109 | private void startForResult(Intent intent) {
110 | if (mActivityOrFragment instanceof Activity) {
111 | ((Activity) mActivityOrFragment).startActivityForResult(intent, mRequestCode);
112 | } else if (mActivityOrFragment instanceof Fragment) {
113 | ((Fragment) mActivityOrFragment).startActivityForResult(intent, mRequestCode);
114 | }
115 | }
116 |
117 | /**
118 | * Display the built dialog.
119 | */
120 | public void show() {
121 | startForResult(AppSettingsDialogHolderActivity.createShowDialogIntent(mContext, this));
122 | }
123 |
124 | public void show(int requestCode, List list) {
125 | Policy.getInstance().showSettingDesDialog(mContext, requestCode, list, this);
126 | }
127 |
128 | public void show(int requestCode, List list, Policy.PolicyClick policyClick) {
129 | Policy.getInstance().showSettingDesDialog(mContext, requestCode, list, policyClick);
130 | }
131 |
132 | /**
133 | * Show the dialog. {@link #show()} is a wrapper to ensure backwards compatibility
134 | */
135 | @SuppressLint("ResourceType")
136 | AlertDialog showDialog(DialogInterface.OnClickListener positiveListener,
137 | DialogInterface.OnClickListener negativeListener) {
138 | AlertDialog.Builder builder;
139 | if (mThemeResId > 0) {
140 | builder = new AlertDialog.Builder(mContext, mThemeResId);
141 | } else {
142 | builder = new AlertDialog.Builder(mContext);
143 | }
144 | return builder
145 | .setCancelable(false)
146 | .setTitle(mTitle)
147 | .setMessage(mRationale)
148 | .setPositiveButton(mPositiveButtonText, positiveListener)
149 | .setNegativeButton(mNegativeButtonText, negativeListener)
150 | .show();
151 | }
152 |
153 | @Override
154 | public int describeContents() {
155 | return 0;
156 | }
157 |
158 | @Override
159 | public void writeToParcel(@NonNull Parcel dest, int flags) {
160 | dest.writeInt(mThemeResId);
161 | dest.writeString(mRationale);
162 | dest.writeString(mTitle);
163 | dest.writeString(mPositiveButtonText);
164 | dest.writeString(mNegativeButtonText);
165 | dest.writeInt(mRequestCode);
166 | dest.writeInt(mIntentFlags);
167 | }
168 |
169 | int getIntentFlags() {
170 | return mIntentFlags;
171 | }
172 |
173 | @Override
174 | public void policyCancelClick(int reqeustCode) {
175 |
176 | }
177 |
178 | /**
179 | * Builder for an {@link AppSettingsDialog}.
180 | */
181 | public static class Builder {
182 |
183 | private final Object mActivityOrFragment;
184 | private final Context mContext;
185 | @StyleRes
186 | private int mThemeResId = -1;
187 | private String mRationale;
188 | private String mTitle;
189 | private String mPositiveButtonText;
190 | private String mNegativeButtonText;
191 | private int mRequestCode = -1;
192 | private boolean mOpenInNewTask = false;
193 |
194 | /**
195 | * Create a new Builder for an {@link AppSettingsDialog}.
196 | *
197 | * @param activity the {@link Activity} in which to display the dialog.
198 | */
199 | public Builder(@NonNull Activity activity) {
200 | mActivityOrFragment = activity;
201 | mContext = activity;
202 | }
203 |
204 | /**
205 | * Create a new Builder for an {@link AppSettingsDialog}.
206 | *
207 | * @param fragment the {@link Fragment} in which to display the dialog.
208 | */
209 | public Builder(@NonNull Fragment fragment) {
210 | mActivityOrFragment = fragment;
211 | mContext = fragment.getContext();
212 | }
213 |
214 | /**
215 | * Set the dialog theme.
216 | */
217 | @NonNull
218 | public Builder setThemeResId(@StyleRes int themeResId) {
219 | mThemeResId = themeResId;
220 | return this;
221 | }
222 |
223 | /**
224 | * Set the title dialog. Default is "Permissions Required".
225 | */
226 | @NonNull
227 | public Builder setTitle(@Nullable String title) {
228 | mTitle = title;
229 | return this;
230 | }
231 |
232 | /**
233 | * Set the title dialog. Default is "Permissions Required".
234 | */
235 | @NonNull
236 | public Builder setTitle(@StringRes int title) {
237 | mTitle = mContext.getString(title);
238 | return this;
239 | }
240 |
241 | /**
242 | * Set the rationale dialog. Default is
243 | * "This app may not work correctly without the requested permissions.
244 | * Open the app settings screen to modify app permissions."
245 | */
246 | @NonNull
247 | public Builder setRationale(@Nullable String rationale) {
248 | mRationale = rationale;
249 | return this;
250 | }
251 |
252 | /**
253 | * Set the rationale dialog. Default is
254 | * "This app may not work correctly without the requested permissions.
255 | * Open the app settings screen to modify app permissions."
256 | */
257 | @NonNull
258 | public Builder setRationale(@StringRes int rationale) {
259 | mRationale = mContext.getString(rationale);
260 | return this;
261 | }
262 |
263 | /**
264 | * Set the positive button text, default is {@link android.R.string#ok}.
265 | */
266 | @NonNull
267 | public Builder setPositiveButton(@Nullable String text) {
268 | mPositiveButtonText = text;
269 | return this;
270 | }
271 |
272 | /**
273 | * Set the positive button text, default is {@link android.R.string#ok}.
274 | */
275 | @NonNull
276 | public Builder setPositiveButton(@StringRes int textId) {
277 | mPositiveButtonText = mContext.getString(textId);
278 | return this;
279 | }
280 |
281 | /**
282 | * Set the negative button text, default is {@link android.R.string#cancel}.
283 | *
284 | * To know if a user cancelled the request, check if your permissions were given with {@link
285 | * EasyPermissions#hasPermissions(Context, String...)} in {@link
286 | * Activity#(int, int, Intent)}. If you still don't have the right
287 | * permissions, then the request was cancelled.
288 | */
289 | @NonNull
290 | public Builder setNegativeButton(@Nullable String text) {
291 | mNegativeButtonText = text;
292 | return this;
293 | }
294 |
295 | /**
296 | * Set the negative button text, default is {@link android.R.string#cancel}.
297 | */
298 | @NonNull
299 | public Builder setNegativeButton(@StringRes int textId) {
300 | mNegativeButtonText = mContext.getString(textId);
301 | return this;
302 | }
303 |
304 | /**
305 | * Set the request code use when launching the Settings screen for result, can be retrieved
306 | * in the calling Activity's {@link Activity#(int, int, Intent)} method.
307 | * Default is {@link #DEFAULT_SETTINGS_REQ_CODE}.
308 | */
309 | @NonNull
310 | public Builder setRequestCode(int requestCode) {
311 | mRequestCode = requestCode;
312 | return this;
313 | }
314 |
315 | /**
316 | * Set whether the settings screen should be opened in a separate task. This is achieved by
317 | * setting {@link Intent#FLAG_ACTIVITY_NEW_TASK#FLAG_ACTIVITY_NEW_TASK} on
318 | * the Intent used to open the settings screen.
319 | */
320 | @NonNull
321 | public Builder setOpenInNewTask(boolean openInNewTask) {
322 | mOpenInNewTask = openInNewTask;
323 | return this;
324 | }
325 |
326 | /**
327 | * Build the {@link AppSettingsDialog} from the specified options. Generally followed by a
328 | * call to {@link AppSettingsDialog#show()}.
329 | */
330 | @NonNull
331 | public AppSettingsDialog build() {
332 | mRationale = TextUtils.isEmpty(mRationale) ?
333 | mContext.getString(R.string.rationale_ask_again) : mRationale;
334 | mTitle = TextUtils.isEmpty(mTitle) ?
335 | mContext.getString(R.string.title_settings_dialog) : mTitle;
336 | mPositiveButtonText = TextUtils.isEmpty(mPositiveButtonText) ?
337 | mContext.getString(android.R.string.ok) : mPositiveButtonText;
338 | mNegativeButtonText = TextUtils.isEmpty(mNegativeButtonText) ?
339 | mContext.getString(android.R.string.cancel) : mNegativeButtonText;
340 | mRequestCode = mRequestCode > 0 ? mRequestCode : DEFAULT_SETTINGS_REQ_CODE;
341 |
342 | int intentFlags = 0;
343 | if (mOpenInNewTask) {
344 | intentFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
345 | }
346 |
347 | return new AppSettingsDialog(
348 | mActivityOrFragment,
349 | mThemeResId,
350 | mRationale,
351 | mTitle,
352 | mPositiveButtonText,
353 | mNegativeButtonText,
354 | mRequestCode,
355 | intentFlags);
356 | }
357 |
358 | }
359 |
360 | }
361 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/AppSettingsDialogHolderActivity.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.content.Context;
6 | import android.content.DialogInterface;
7 | import android.content.Intent;
8 | import android.net.Uri;
9 | import android.os.Bundle;
10 | import android.provider.Settings;
11 |
12 | import androidx.annotation.RestrictTo;
13 | import androidx.appcompat.app.AppCompatActivity;
14 |
15 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
16 | public class AppSettingsDialogHolderActivity extends AppCompatActivity implements DialogInterface.OnClickListener {
17 | private static final int APP_SETTINGS_RC = 7534;
18 |
19 | private Dialog mDialog;
20 | private int mIntentFlags;
21 |
22 | public static Intent createShowDialogIntent(Context context, AppSettingsDialog dialog) {
23 | Intent intent = new Intent(context, AppSettingsDialogHolderActivity.class);
24 | intent.putExtra(AppSettingsDialog.EXTRA_APP_SETTINGS, dialog);
25 | return intent;
26 | }
27 |
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | AppSettingsDialog appSettingsDialog = AppSettingsDialog.fromIntent(getIntent(), this);
32 | mIntentFlags = appSettingsDialog.getIntentFlags();
33 | mDialog = appSettingsDialog.showDialog(this, this);
34 | }
35 |
36 | @Override
37 | protected void onDestroy() {
38 | super.onDestroy();
39 | if (mDialog != null && mDialog.isShowing()) {
40 | mDialog.dismiss();
41 | }
42 | }
43 |
44 | @Override
45 | public void onClick(DialogInterface dialog, int which) {
46 | if (which == Dialog.BUTTON_POSITIVE) {
47 | Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
48 | .setData(Uri.fromParts("package", getPackageName(), null));
49 | intent.addFlags(mIntentFlags);
50 | startActivityForResult(intent, APP_SETTINGS_RC);
51 | } else if (which == Dialog.BUTTON_NEGATIVE) {
52 | setResult(Activity.RESULT_CANCELED);
53 | finish();
54 | } else {
55 | throw new IllegalStateException("Unknown button type: " + which);
56 | }
57 | }
58 |
59 | @Override
60 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
61 | super.onActivityResult(requestCode, resultCode, data);
62 | setResult(resultCode, data);
63 | finish();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/EasyPermissions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package pub.devrel.easypermissions;
17 |
18 | import android.Manifest;
19 | import android.app.Activity;
20 | import android.content.Context;
21 | import android.content.pm.PackageManager;
22 | import android.os.Build;
23 | import android.util.Log;
24 |
25 | import androidx.annotation.NonNull;
26 | import androidx.annotation.Size;
27 | import androidx.core.app.ActivityCompat;
28 | import androidx.core.content.ContextCompat;
29 | import androidx.fragment.app.Fragment;
30 |
31 | import com.db.policylib.PermissionPolicy;
32 | import com.db.policylib.Policy;
33 |
34 | import java.lang.reflect.InvocationTargetException;
35 | import java.lang.reflect.Method;
36 | import java.util.ArrayList;
37 | import java.util.List;
38 |
39 | import pub.devrel.easypermissions.helper.PermissionHelper;
40 |
41 | /**
42 | * Utility to request and check System permissions for apps targeting Android M (API >= 23).
43 | */
44 | public class EasyPermissions {
45 |
46 | /**
47 | * Callback interface to receive the results of {@code EasyPermissions.requestPermissions()}
48 | * calls.
49 | */
50 | public interface PermissionCallbacks extends ActivityCompat.OnRequestPermissionsResultCallback {
51 |
52 | void onPermissionsGranted(int requestCode, @NonNull List perms);
53 |
54 | void onPermissionsDenied(int requestCode, @NonNull List perms);
55 | }
56 |
57 | /**
58 | * Callback interface to receive button clicked events of the rationale dialog
59 | */
60 | public interface RationaleCallbacks {
61 | void onRationaleAccepted(int requestCode);
62 |
63 | void onRationaleDenied(int requestCode);
64 | }
65 |
66 | private static final String TAG = "EasyPermissions";
67 | private static Context context;
68 |
69 | /**
70 | * Check if the calling context has a set of permissions.
71 | *
72 | * @param context the calling context.
73 | * @param perms one ore more permissions, such as {@link Manifest.permission#CAMERA}.
74 | * @return true if all permissions are already granted, false if at least one permission is not
75 | * yet granted.
76 | * @see Manifest.permission
77 | */
78 | public static boolean hasPermissions(@NonNull Context context,
79 | @Size(min = 1) @NonNull String... perms) {
80 | // Always return true for SDK < M, let the system deal with the permissions
81 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
82 | Log.w(TAG, "hasPermissions: API version < M, returning true by default");
83 |
84 | // DANGER ZONE!!! Changing this will break the library.
85 | return true;
86 | }
87 |
88 | // Null context may be passed if we have detected Low API (less than M) so getting
89 | // to this point with a null context should not be possible.
90 | if (context == null) {
91 | throw new IllegalArgumentException("Can't check permissions for null context");
92 | }
93 |
94 | for (String perm : perms) {
95 | if (ContextCompat.checkSelfPermission(context, perm)
96 | != PackageManager.PERMISSION_GRANTED) {
97 | return false;
98 | }
99 | }
100 |
101 | return true;
102 | }
103 |
104 | /**
105 | * Request a set of permissions, showing a rationale if the system requests it.
106 | *
107 | * @param host requesting context.
108 | * @param rationale a message explaining why the application needs this set of permissions;
109 | * will be displayed if the user rejects the request the first time.
110 | * @param requestCode request code to track this request, must be < 256.
111 | * @param perms a set of permissions to be requested.
112 | * @see Manifest.permission
113 | */
114 | public static void requestPermissions(
115 | @NonNull Activity host, @NonNull String rationale,
116 | int requestCode, List list, @Size(min = 1) @NonNull String... perms) {
117 | context = (Context) host;
118 | for (int i = 0; i < list.size(); i++) {
119 | PermissionPolicy policy = list.get(i);
120 | if (EasyPermissions.hasPermissions(host, policy.getPermission())) {
121 | list.remove(i);
122 | perms[i].replace(perms[i], "");
123 | }
124 | }
125 | requestPermissions(
126 | new PermissionRequest.Builder(host, requestCode, list, perms)
127 | .setRationale(rationale)
128 | .build());
129 | }
130 |
131 | /**
132 | * Request permissions from a Support Fragment with standard OK/Cancel buttons.
133 | *
134 | * @see #(Activity, String, int, String...)
135 | */
136 | public static void requestPermissions(
137 | @NonNull Fragment host, @NonNull String rationale,
138 | int requestCode, List list, @Size(min = 1) @NonNull String... perms) {
139 | context = ((Fragment) host).getContext();
140 | requestPermissions(
141 | new PermissionRequest.Builder(host, requestCode, list, perms)
142 | .setRationale(rationale)
143 | .build());
144 | }
145 |
146 | /**
147 | * Request a set of permissions.
148 | *
149 | * @param request the permission request
150 | * @see PermissionRequest
151 | */
152 | public static void requestPermissions(PermissionRequest request) {
153 |
154 | // Check for permissions before dispatching the request
155 | if (hasPermissions(request.getHelper().getContext(), request.getPerms())) {
156 | notifyAlreadyHasPermissions(
157 | request.getHelper().getHost(), request.getRequestCode(), request.getPerms());
158 | return;
159 | }
160 | // Request permissions
161 | request.getHelper().requestPermissions(
162 | request.getRationale(),
163 | request.getPositiveButtonText(),
164 | request.getNegativeButtonText(),
165 | request.getTheme(),
166 | request.getRequestCode(), request.getPermissions(),
167 | request.getPerms());
168 | }
169 |
170 | /**
171 | * Handle the result of a permission request, should be called from the calling {@link
172 | * Activity}'s {@link ActivityCompat.OnRequestPermissionsResultCallback#onRequestPermissionsResult(int,
173 | * String[], int[])} method.
174 | *
175 | * If any permissions were granted or denied, the {@code object} will receive the appropriate
176 | * callbacks through {@link PermissionCallbacks} and methods annotated with {@link
177 | * AfterPermissionGranted} will be run if appropriate.
178 | *
179 | * @param requestCode requestCode argument to permission result callback.
180 | * @param permissions permissions argument to permission result callback.
181 | * @param grantResults grantResults argument to permission result callback.
182 | * @param receivers an array of objects that have a method annotated with {@link
183 | * AfterPermissionGranted} or implement {@link PermissionCallbacks}.
184 | */
185 | public static void onRequestPermissionsResult(int requestCode,
186 | @NonNull String[] permissions,
187 | @NonNull int[] grantResults,
188 | @NonNull Object... receivers) {
189 | // Make a collection of granted and denied permissions from the request.
190 | List granted = new ArrayList<>();
191 | List denied = new ArrayList<>();
192 | for (int i = 0; i < permissions.length; i++) {
193 | String perm = permissions[i];
194 | if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
195 | granted.add(perm);
196 | } else {
197 | denied.add(perm);
198 | }
199 | }
200 |
201 | // iterate through all receivers
202 | for (Object object : receivers) {
203 | // Report granted permissions, if any.
204 | if (!granted.isEmpty()) {
205 | if (object instanceof PermissionCallbacks) {
206 | ((PermissionCallbacks) object).onPermissionsGranted(requestCode, granted);
207 | }
208 | }
209 |
210 | // Report denied permissions, if any.
211 | if (!denied.isEmpty()) {
212 | if (object instanceof PermissionCallbacks) {
213 | for (int i = 0; i < denied.size(); i++) {
214 | Policy.getInstance().putString(context, denied.get(i));
215 | }
216 | ((PermissionCallbacks) object).onPermissionsDenied(requestCode, denied);
217 | }
218 | }
219 |
220 | // If 100% successful, call annotated methods
221 | if (!granted.isEmpty() && denied.isEmpty()) {
222 | runAnnotatedMethods(object, requestCode);
223 | }
224 | }
225 | }
226 |
227 | /**
228 | * Check if at least one permission in the list of denied permissions has been permanently
229 | * denied (user clicked "Never ask again").
230 | *
231 | * Note: Due to a limitation in the information provided by the Android
232 | * framework permissions API, this method only works after the permission
233 | * has been denied and your app has received the onPermissionsDenied callback.
234 | * Otherwise the library cannot distinguish permanent denial from the
235 | * "not yet denied" case.
236 | *
237 | * @param host context requesting permissions.
238 | * @param deniedPermissions list of denied permissions, usually from {@link
239 | * PermissionCallbacks#onPermissionsDenied(int, List)}
240 | * @return {@code true} if at least one permission in the list was permanently denied.
241 | */
242 | public static boolean somePermissionPermanentlyDenied(@NonNull Activity host,
243 | @NonNull List deniedPermissions) {
244 | return PermissionHelper.newInstance(host)
245 | .somePermissionPermanentlyDenied(deniedPermissions);
246 | }
247 |
248 | /**
249 | * @see #somePermissionPermanentlyDenied(Activity, List)
250 | */
251 | public static boolean somePermissionPermanentlyDenied(@NonNull Fragment host,
252 | @NonNull List deniedPermissions) {
253 | return PermissionHelper.newInstance(host)
254 | .somePermissionPermanentlyDenied(deniedPermissions);
255 | }
256 |
257 | /**
258 | * Check if a permission has been permanently denied (user clicked "Never ask again").
259 | *
260 | * @param host context requesting permissions.
261 | * @param deniedPermission denied permission.
262 | * @return {@code true} if the permissions has been permanently denied.
263 | */
264 | public static boolean permissionPermanentlyDenied(@NonNull Activity host,
265 | @NonNull String deniedPermission) {
266 | return PermissionHelper.newInstance(host).permissionPermanentlyDenied(deniedPermission);
267 | }
268 |
269 | /**
270 | * @see #permissionPermanentlyDenied(Activity, String)
271 | */
272 | public static boolean permissionPermanentlyDenied(@NonNull Fragment host,
273 | @NonNull String deniedPermission) {
274 | return PermissionHelper.newInstance(host).permissionPermanentlyDenied(deniedPermission);
275 | }
276 |
277 | /**
278 | * See if some denied permission has been permanently denied.
279 | *
280 | * @param host requesting context.
281 | * @param perms array of permissions.
282 | * @return true if the user has previously denied any of the {@code perms} and we should show a
283 | * rationale, false otherwise.
284 | */
285 | public static boolean somePermissionDenied(@NonNull Activity host,
286 | @NonNull String... perms) {
287 | return PermissionHelper.newInstance(host).somePermissionDenied(perms);
288 | }
289 |
290 | /**
291 | * @see #somePermissionDenied(Activity, String...)
292 | */
293 | public static boolean somePermissionDenied(@NonNull Fragment host,
294 | @NonNull String... perms) {
295 | return PermissionHelper.newInstance(host).somePermissionDenied(perms);
296 | }
297 |
298 | /**
299 | * Run permission callbacks on an object that requested permissions but already has them by
300 | * simulating {@link PackageManager#PERMISSION_GRANTED}.
301 | *
302 | * @param object the object requesting permissions.
303 | * @param requestCode the permission request code.
304 | * @param perms a list of permissions requested.
305 | */
306 | private static void notifyAlreadyHasPermissions(@NonNull Object object,
307 | int requestCode,
308 | @NonNull String[] perms) {
309 | int[] grantResults = new int[perms.length];
310 | for (int i = 0; i < perms.length; i++) {
311 | grantResults[i] = PackageManager.PERMISSION_GRANTED;
312 | }
313 |
314 | onRequestPermissionsResult(requestCode, perms, grantResults, object);
315 | }
316 |
317 | /**
318 | * Find all methods annotated with {@link AfterPermissionGranted} on a given object with the
319 | * correct requestCode argument.
320 | *
321 | * @param object the object with annotated methods.
322 | * @param requestCode the requestCode passed to the annotation.
323 | */
324 | private static void runAnnotatedMethods(@NonNull Object object, int requestCode) {
325 | Class clazz = object.getClass();
326 | if (isUsingAndroidAnnotations(object)) {
327 | clazz = clazz.getSuperclass();
328 | }
329 |
330 | while (clazz != null) {
331 | for (Method method : clazz.getDeclaredMethods()) {
332 | AfterPermissionGranted ann = method.getAnnotation(AfterPermissionGranted.class);
333 | if (ann != null) {
334 | // Check for annotated methods with matching request code.
335 | if (ann.value() == requestCode) {
336 | // Method must be void so that we can invoke it
337 | if (method.getParameterTypes().length > 0) {
338 | throw new RuntimeException(
339 | "Cannot execute method " + method.getName() + " because it is non-void method and/or has input parameters.");
340 | }
341 |
342 | try {
343 | // Make method accessible if private
344 | if (!method.isAccessible()) {
345 | method.setAccessible(true);
346 | }
347 | method.invoke(object);
348 | } catch (IllegalAccessException e) {
349 | Log.e(TAG, "runDefaultMethod:IllegalAccessException", e);
350 | } catch (InvocationTargetException e) {
351 | Log.e(TAG, "runDefaultMethod:InvocationTargetException", e);
352 | }
353 | }
354 | }
355 | }
356 |
357 | clazz = clazz.getSuperclass();
358 | }
359 | }
360 |
361 | /**
362 | * Determine if the project is using the AndroidAnnotations library.
363 | */
364 | private static boolean isUsingAndroidAnnotations(@NonNull Object object) {
365 | if (!object.getClass().getSimpleName().endsWith("_")) {
366 | return false;
367 | }
368 | try {
369 | Class clazz = Class.forName("org.androidannotations.api.view.HasViews");
370 | return clazz.isInstance(object);
371 | } catch (ClassNotFoundException e) {
372 | return false;
373 | }
374 | }
375 | }
376 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/PermissionRequest.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions;
2 |
3 | import android.app.Activity;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.annotation.Nullable;
7 | import androidx.annotation.RestrictTo;
8 | import androidx.annotation.Size;
9 | import androidx.annotation.StringRes;
10 | import androidx.annotation.StyleRes;
11 | import androidx.fragment.app.Fragment;
12 |
13 | import com.db.policylib.PermissionPolicy;
14 | import com.db.policylib.R;
15 |
16 | import java.util.Arrays;
17 | import java.util.List;
18 |
19 | import pub.devrel.easypermissions.helper.PermissionHelper;
20 |
21 | /**
22 | * An immutable model object that holds all of the parameters associated with a permission request,
23 | * such as the permissions, request code, and rationale.
24 | *
25 | * @see EasyPermissions#requestPermissions(PermissionRequest)
26 | * @see PermissionRequest.Builder
27 | */
28 | public final class PermissionRequest {
29 | private final PermissionHelper mHelper;
30 | private final String[] mPerms;
31 | private final int mRequestCode;
32 | private final String mRationale;
33 | private final String mPositiveButtonText;
34 | private final String mNegativeButtonText;
35 | private final int mTheme;
36 | private final List list;
37 |
38 | private PermissionRequest(PermissionHelper helper,
39 | String[] perms,
40 | int requestCode, List list,
41 | String rationale,
42 | String positiveButtonText,
43 | String negativeButtonText,
44 | int theme) {
45 | mHelper = helper;
46 | mPerms = perms.clone();
47 | mRequestCode = requestCode;
48 | this.list = list;
49 | mRationale = rationale;
50 | mPositiveButtonText = positiveButtonText;
51 | mNegativeButtonText = negativeButtonText;
52 | mTheme = theme;
53 | }
54 |
55 | @NonNull
56 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
57 | public PermissionHelper getHelper() {
58 | return mHelper;
59 | }
60 |
61 | @NonNull
62 | public String[] getPerms() {
63 | return mPerms.clone();
64 | }
65 |
66 | public int getRequestCode() {
67 | return mRequestCode;
68 | }
69 |
70 | public List getPermissions() {
71 | return list;
72 | }
73 |
74 |
75 | @NonNull
76 | public String getRationale() {
77 | return mRationale;
78 | }
79 |
80 | @NonNull
81 | public String getPositiveButtonText() {
82 | return mPositiveButtonText;
83 | }
84 |
85 | @NonNull
86 | public String getNegativeButtonText() {
87 | return mNegativeButtonText;
88 | }
89 |
90 | @StyleRes
91 | public int getTheme() {
92 | return mTheme;
93 | }
94 |
95 | @Override
96 | public boolean equals(Object o) {
97 | if (this == o) return true;
98 | if (o == null || getClass() != o.getClass()) return false;
99 |
100 | PermissionRequest request = (PermissionRequest) o;
101 |
102 | return Arrays.equals(mPerms, request.mPerms) && mRequestCode == request.mRequestCode;
103 | }
104 |
105 | @Override
106 | public int hashCode() {
107 | int result = Arrays.hashCode(mPerms);
108 | result = 31 * result + mRequestCode;
109 | return result;
110 | }
111 |
112 | @Override
113 | public String toString() {
114 | return "PermissionRequest{" +
115 | "mHelper=" + mHelper +
116 | ", mPerms=" + Arrays.toString(mPerms) +
117 | ", mRequestCode=" + mRequestCode +
118 | ", mRationale='" + mRationale + '\'' +
119 | ", mPositiveButtonText='" + mPositiveButtonText + '\'' +
120 | ", mNegativeButtonText='" + mNegativeButtonText + '\'' +
121 | ", mTheme=" + mTheme +
122 | '}';
123 | }
124 |
125 | /**
126 | * Builder to build a permission request with variable options.
127 | *
128 | * @see PermissionRequest
129 | */
130 | public static final class Builder {
131 | private final PermissionHelper mHelper;
132 | private final int mRequestCode;
133 | private final String[] mPerms;
134 | private List lists;
135 | private String mRationale;
136 | private String mPositiveButtonText;
137 | private String mNegativeButtonText;
138 | private int mTheme = -1;
139 |
140 | /**
141 | * Construct a new permission request builder with a host, request code, and the requested
142 | * permissions.
143 | *
144 | * @param activity the permission request host
145 | * @param requestCode request code to track this request; must be < 256
146 | * @param perms the set of permissions to be requested
147 | */
148 | public Builder(@NonNull Activity activity, int requestCode, List list,
149 | @NonNull @Size(min = 1) String... perms) {
150 | mHelper = PermissionHelper.newInstance(activity);
151 | mRequestCode = requestCode;
152 | lists = list;
153 | mPerms = perms;
154 | }
155 |
156 | /**
157 | * @see #(Activity, int, String...)
158 | */
159 | public Builder(@NonNull Fragment fragment, int requestCode, List list,
160 | @NonNull @Size(min = 1) String... perms) {
161 | mHelper = PermissionHelper.newInstance(fragment);
162 | mRequestCode = requestCode;
163 | lists = list;
164 | mPerms = perms;
165 | }
166 |
167 | /**
168 | * Set the rationale to display to the user if they don't allow your permissions on the
169 | * first try. This rationale will be shown as long as the user has denied your permissions
170 | * at least once, but has not yet permanently denied your permissions. Should the user
171 | * permanently deny your permissions, use the {@link AppSettingsDialog} instead.
172 | *
173 | * The default rationale text is {@link R.string#rationale_ask}.
174 | *
175 | * @param rationale the rationale to be displayed to the user should they deny your
176 | * permission at least once
177 | */
178 | @NonNull
179 | public Builder setRationale(@Nullable String rationale) {
180 | mRationale = rationale;
181 | return this;
182 | }
183 |
184 | /**
185 | * @param resId the string resource to be used as a rationale
186 | * @see #setRationale(String)
187 | */
188 | @NonNull
189 | public Builder setRationale(@StringRes int resId) {
190 | mRationale = mHelper.getContext().getString(resId);
191 | return this;
192 | }
193 |
194 | /**
195 | * Set the positive button text for the rationale dialog should it be shown.
196 | *
197 | * The default is {@link android.R.string#ok}
198 | */
199 | @NonNull
200 | public Builder setPositiveButtonText(@Nullable String positiveButtonText) {
201 | mPositiveButtonText = positiveButtonText;
202 | return this;
203 | }
204 |
205 | /**
206 | * @see #setPositiveButtonText(String)
207 | */
208 | @NonNull
209 | public Builder setPositiveButtonText(@StringRes int resId) {
210 | mPositiveButtonText = mHelper.getContext().getString(resId);
211 | return this;
212 | }
213 |
214 | /**
215 | * Set the negative button text for the rationale dialog should it be shown.
216 | *
217 | * The default is {@link android.R.string#cancel}
218 | */
219 | @NonNull
220 | public Builder setNegativeButtonText(@Nullable String negativeButtonText) {
221 | mNegativeButtonText = negativeButtonText;
222 | return this;
223 | }
224 |
225 | /**
226 | * @see #setNegativeButtonText(String)
227 | */
228 | @NonNull
229 | public Builder setNegativeButtonText(@StringRes int resId) {
230 | mNegativeButtonText = mHelper.getContext().getString(resId);
231 | return this;
232 | }
233 |
234 | /**
235 | * Set the theme to be used for the rationale dialog should it be shown.
236 | *
237 | * @param theme a style resource
238 | */
239 | @NonNull
240 | public Builder setTheme(@StyleRes int theme) {
241 | mTheme = theme;
242 | return this;
243 | }
244 |
245 | /**
246 | * Build the permission request.
247 | *
248 | * @return the permission request
249 | * @see EasyPermissions#requestPermissions(PermissionRequest)
250 | * @see PermissionRequest
251 | */
252 | @NonNull
253 | public PermissionRequest build() {
254 | if (mRationale == null) {
255 | mRationale = mHelper.getContext().getString(R.string.rationale_ask);
256 | }
257 | if (mPositiveButtonText == null) {
258 | mPositiveButtonText = mHelper.getContext().getString(android.R.string.ok);
259 | }
260 | if (mNegativeButtonText == null) {
261 | mNegativeButtonText = mHelper.getContext().getString(android.R.string.cancel);
262 | }
263 |
264 | return new PermissionRequest(
265 | mHelper,
266 | mPerms,
267 | mRequestCode, lists,
268 | mRationale,
269 | mPositiveButtonText,
270 | mNegativeButtonText,
271 | mTheme);
272 | }
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/RationaleClickListener.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions;
2 |
3 | import android.app.Activity;
4 |
5 | import androidx.fragment.app.Fragment;
6 |
7 | import java.util.Arrays;
8 |
9 | import pub.devrel.easypermissions.helper.PermissionHelper;
10 |
11 | public class RationaleClickListener {
12 |
13 | private Object mHost;
14 | private RationaleDialogConfig mConfig;
15 | private EasyPermissions.PermissionCallbacks mCallbacks;
16 | private EasyPermissions.RationaleCallbacks mRationaleCallbacks;
17 |
18 | RationaleClickListener(RationaleDialogFragmentCompat compatDialogFragment,
19 | RationaleDialogConfig config,
20 | EasyPermissions.PermissionCallbacks callbacks,
21 | EasyPermissions.RationaleCallbacks rationaleCallbacks) {
22 |
23 | mHost = compatDialogFragment.getParentFragment() != null
24 | ? compatDialogFragment.getParentFragment()
25 | : compatDialogFragment.getActivity();
26 |
27 | mConfig = config;
28 | mCallbacks = callbacks;
29 | mRationaleCallbacks = rationaleCallbacks;
30 |
31 | }
32 |
33 | RationaleClickListener(RationaleDialogFragment dialogFragment,
34 | RationaleDialogConfig config,
35 | EasyPermissions.PermissionCallbacks callbacks,
36 | EasyPermissions.RationaleCallbacks dialogCallback) {
37 |
38 | mHost = dialogFragment.getActivity();
39 |
40 | mConfig = config;
41 | mCallbacks = callbacks;
42 | mRationaleCallbacks = dialogCallback;
43 | }
44 |
45 | public void onClick(int which) {
46 | int requestCode = mConfig.requestCode;
47 | if (which == 0) {
48 | String[] permissions = mConfig.permissions;
49 | if (mRationaleCallbacks != null) {
50 | mRationaleCallbacks.onRationaleAccepted(requestCode);
51 | }
52 | if (mHost instanceof Fragment) {
53 | PermissionHelper.newInstance((Fragment) mHost).directRequestPermissions(requestCode, permissions);
54 | } else if (mHost instanceof Activity) {
55 | PermissionHelper.newInstance((Activity) mHost).directRequestPermissions(requestCode, permissions);
56 | } else {
57 | throw new RuntimeException("Host must be an Activity or Fragment!");
58 | }
59 | } else {
60 | if (mRationaleCallbacks != null) {
61 | mRationaleCallbacks.onRationaleDenied(requestCode);
62 | }
63 | // notifyPermissionDenied();
64 | }
65 | }
66 |
67 | private void notifyPermissionDenied() {
68 | if (mCallbacks != null) {
69 | mCallbacks.onPermissionsDenied(mConfig.requestCode, Arrays.asList(mConfig.permissions));
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/RationaleDialogClickListener.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.content.DialogInterface;
6 |
7 | import androidx.fragment.app.Fragment;
8 |
9 | import java.util.Arrays;
10 |
11 | import pub.devrel.easypermissions.helper.PermissionHelper;
12 |
13 | /**
14 | * Click listener for either {@link RationaleDialogFragment} or {@link RationaleDialogFragmentCompat}.
15 | */
16 | class RationaleDialogClickListener implements Dialog.OnClickListener {
17 |
18 | private Object mHost;
19 | private RationaleDialogConfig mConfig;
20 | private EasyPermissions.PermissionCallbacks mCallbacks;
21 | private EasyPermissions.RationaleCallbacks mRationaleCallbacks;
22 |
23 | RationaleDialogClickListener(RationaleDialogFragmentCompat compatDialogFragment,
24 | RationaleDialogConfig config,
25 | EasyPermissions.PermissionCallbacks callbacks,
26 | EasyPermissions.RationaleCallbacks rationaleCallbacks) {
27 |
28 | mHost = compatDialogFragment.getParentFragment() != null
29 | ? compatDialogFragment.getParentFragment()
30 | : compatDialogFragment.getActivity();
31 |
32 | mConfig = config;
33 | mCallbacks = callbacks;
34 | mRationaleCallbacks = rationaleCallbacks;
35 |
36 | }
37 |
38 | RationaleDialogClickListener(RationaleDialogFragment dialogFragment,
39 | RationaleDialogConfig config,
40 | EasyPermissions.PermissionCallbacks callbacks,
41 | EasyPermissions.RationaleCallbacks dialogCallback) {
42 |
43 | mHost = dialogFragment.getActivity();
44 |
45 | mConfig = config;
46 | mCallbacks = callbacks;
47 | mRationaleCallbacks = dialogCallback;
48 | }
49 |
50 | @Override
51 | public void onClick(DialogInterface dialog, int which) {
52 | int requestCode = mConfig.requestCode;
53 | if (which == Dialog.BUTTON_POSITIVE) {
54 | String[] permissions = mConfig.permissions;
55 | if (mRationaleCallbacks != null) {
56 | mRationaleCallbacks.onRationaleAccepted(requestCode);
57 | }
58 | if (mHost instanceof Fragment) {
59 | PermissionHelper.newInstance((Fragment) mHost).directRequestPermissions(requestCode, permissions);
60 | } else if (mHost instanceof Activity) {
61 | PermissionHelper.newInstance((Activity) mHost).directRequestPermissions(requestCode, permissions);
62 | } else {
63 | throw new RuntimeException("Host must be an Activity or Fragment!");
64 | }
65 | } else {
66 | if (mRationaleCallbacks != null) {
67 | mRationaleCallbacks.onRationaleDenied(requestCode);
68 | }
69 | notifyPermissionDenied();
70 | }
71 | }
72 |
73 | private void notifyPermissionDenied() {
74 | if (mCallbacks != null) {
75 | mCallbacks.onPermissionsDenied(mConfig.requestCode, Arrays.asList(mConfig.permissions));
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/RationaleDialogConfig.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.widget.LinearLayout;
8 | import android.widget.TextView;
9 |
10 | import androidx.annotation.NonNull;
11 | import androidx.annotation.StyleRes;
12 | import androidx.recyclerview.widget.LinearLayoutManager;
13 | import androidx.recyclerview.widget.RecyclerView;
14 |
15 | import com.db.policylib.PermissionPolicy;
16 | import com.db.policylib.Policy;
17 | import com.db.policylib.PolicyAdapter;
18 | import com.db.policylib.R;
19 |
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | /**
24 | * Configuration for either {@link RationaleDialogFragment} or {@link RationaleDialogFragmentCompat}.
25 | */
26 | class RationaleDialogConfig {
27 |
28 | private static final String KEY_POSITIVE_BUTTON = "positiveButton";
29 | private static final String KEY_NEGATIVE_BUTTON = "negativeButton";
30 | private static final String KEY_RATIONALE_MESSAGE = "rationaleMsg";
31 | private static final String KEY_THEME = "theme";
32 | private static final String KEY_REQUEST_CODE = "requestCode";
33 | private static final String KEY_PERMISSIONS = "permissions";
34 | private static final String KEY_PERMISSION_LIST = "permissionList";
35 | String positiveButton;
36 | String negativeButton;
37 | int theme;
38 | int requestCode;
39 | String rationaleMsg;
40 | String[] permissions;
41 | List lists;
42 |
43 | RationaleDialogConfig(@NonNull String positiveButton,
44 | @NonNull String negativeButton,
45 | @NonNull String rationaleMsg,
46 | @StyleRes int theme,
47 | int requestCode, List list,
48 | @NonNull String[] permissions) {
49 |
50 | this.positiveButton = positiveButton;
51 | this.negativeButton = negativeButton;
52 | this.rationaleMsg = rationaleMsg;
53 | this.theme = theme;
54 | this.lists = list;
55 | this.requestCode = requestCode;
56 | this.permissions = permissions;
57 | }
58 |
59 | RationaleDialogConfig(Bundle bundle) {
60 | positiveButton = bundle.getString(KEY_POSITIVE_BUTTON);
61 | negativeButton = bundle.getString(KEY_NEGATIVE_BUTTON);
62 | rationaleMsg = bundle.getString(KEY_RATIONALE_MESSAGE);
63 | theme = bundle.getInt(KEY_THEME);
64 | requestCode = bundle.getInt(KEY_REQUEST_CODE);
65 | lists = (List) bundle.getSerializable(KEY_PERMISSION_LIST);
66 | permissions = bundle.getStringArray(KEY_PERMISSIONS);
67 | }
68 |
69 | Bundle toBundle() {
70 | Bundle bundle = new Bundle();
71 | bundle.putString(KEY_POSITIVE_BUTTON, positiveButton);
72 | bundle.putString(KEY_NEGATIVE_BUTTON, negativeButton);
73 | bundle.putString(KEY_RATIONALE_MESSAGE, rationaleMsg);
74 | bundle.putInt(KEY_THEME, theme);
75 | bundle.putInt(KEY_REQUEST_CODE, requestCode);
76 | bundle.putSerializable(KEY_PERMISSION_LIST, (ArrayList) lists);
77 | bundle.putStringArray(KEY_PERMISSIONS, permissions);
78 |
79 | return bundle;
80 | }
81 |
82 | Dialog createSupportDialog(Context context, final RationaleClickListener listener) {
83 | final Dialog dialog = new Dialog(context, R.style.POLICY_DIALOG);
84 | dialog.setCanceledOnTouchOutside(false);
85 | dialog.setCancelable(false);
86 | dialog.setContentView(R.layout.layout_policy);
87 | dialog.show();
88 | LinearLayout ll_bottom = dialog.findViewById(R.id.ll_bottom);
89 | RecyclerView rv_list = dialog.findViewById(R.id.rv_list);
90 | TextView tv_title = dialog.findViewById(R.id.tv_title);
91 | TextView tv_request = dialog.findViewById(R.id.tv_request);
92 | TextView tv_ok = dialog.findViewById(R.id.tv_ok);
93 | TextView tv_cancel = dialog.findViewById(R.id.tv_cancel);
94 | ll_bottom.setVisibility(View.VISIBLE);
95 | tv_request.setVisibility(View.GONE);
96 | if (!Policy.getInstance().getTitle().equals(Policy.TITLE)) {
97 | tv_title.setText(Policy.getInstance().getTitle());
98 | }
99 | PolicyAdapter adapter = new PolicyAdapter(context, lists);
100 | rv_list.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
101 | rv_list.setAdapter(adapter);
102 | tv_ok.setOnClickListener(new View.OnClickListener() {
103 | @Override
104 | public void onClick(View v) {
105 | dialog.dismiss();
106 | if (listener != null) {
107 | listener.onClick(0);
108 | }
109 | }
110 | });
111 | tv_request.setOnClickListener(new View.OnClickListener() {
112 | @Override
113 | public void onClick(View v) {
114 | dialog.dismiss();
115 | if (listener != null) {
116 | listener.onClick(0);
117 | }
118 | }
119 | });
120 | tv_cancel.setOnClickListener(new View.OnClickListener() {
121 | @Override
122 | public void onClick(View v) {
123 | dialog.dismiss();
124 | if (listener != null) {
125 | listener.onClick(1);
126 | }
127 | }
128 | });
129 | return dialog;
130 | }
131 |
132 | Dialog createFrameworkDialog(Context context, final RationaleClickListener listener) {
133 | final Dialog dialog = new Dialog(context, R.style.POLICY_DIALOG);
134 | dialog.setCanceledOnTouchOutside(false);
135 | dialog.setCancelable(false);
136 | dialog.setContentView(R.layout.layout_policy);
137 | dialog.show();
138 | LinearLayout ll_bottom = dialog.findViewById(R.id.ll_bottom);
139 | RecyclerView rv_list = dialog.findViewById(R.id.rv_list);
140 | TextView tv_title = dialog.findViewById(R.id.tv_title);
141 | TextView tv_request = dialog.findViewById(R.id.tv_request);
142 | TextView tv_ok = dialog.findViewById(R.id.tv_ok);
143 | TextView tv_cancel = dialog.findViewById(R.id.tv_cancel);
144 | ll_bottom.setVisibility(View.VISIBLE);
145 | tv_request.setVisibility(View.GONE);
146 | if (!Policy.getInstance().getTitle().equals(Policy.TITLE)) {
147 | tv_title.setText(Policy.getInstance().getTitle());
148 | }
149 | PolicyAdapter adapter = new PolicyAdapter(context, lists);
150 | rv_list.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
151 | rv_list.setAdapter(adapter);
152 | tv_ok.setOnClickListener(new View.OnClickListener() {
153 | @Override
154 | public void onClick(View v) {
155 | dialog.dismiss();
156 | if (listener != null) {
157 | listener.onClick(0);
158 | }
159 | }
160 | });
161 | tv_request.setOnClickListener(new View.OnClickListener() {
162 | @Override
163 | public void onClick(View v) {
164 | dialog.dismiss();
165 | if (listener != null) {
166 | listener.onClick(0);
167 | }
168 | }
169 | });
170 | tv_cancel.setOnClickListener(new View.OnClickListener() {
171 | @Override
172 | public void onClick(View v) {
173 | dialog.dismiss();
174 | if (listener != null) {
175 | listener.onClick(1);
176 | }
177 | }
178 | });
179 | return dialog;
180 | }
181 |
182 | }
183 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/RationaleDialogFragment.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions;
2 |
3 | import android.app.Dialog;
4 | import android.app.DialogFragment;
5 | import android.app.FragmentManager;
6 | import android.content.Context;
7 | import android.os.Build;
8 | import android.os.Bundle;
9 |
10 | import androidx.annotation.NonNull;
11 | import androidx.annotation.RestrictTo;
12 | import androidx.annotation.StyleRes;
13 |
14 | import com.db.policylib.PermissionPolicy;
15 |
16 | import java.util.List;
17 |
18 | /**
19 | * {@link DialogFragment} to display rationale for permission requests when the request comes from
20 | * a Fragment or Activity that can host a Fragment.
21 | */
22 | @RestrictTo(RestrictTo.Scope.LIBRARY)
23 | public class RationaleDialogFragment extends DialogFragment {
24 |
25 | public static final String TAG = "RationaleDialogFragment";
26 |
27 | private EasyPermissions.PermissionCallbacks mPermissionCallbacks;
28 | private EasyPermissions.RationaleCallbacks mRationaleCallbacks;
29 | private boolean mStateSaved = false;
30 | private static List lists;
31 |
32 | public static RationaleDialogFragment newInstance(
33 | @NonNull String positiveButton,
34 | @NonNull String negativeButton,
35 | @NonNull String rationaleMsg,
36 | @StyleRes int theme,
37 | int requestCode, List list,
38 | @NonNull String[] permissions) {
39 | lists = list;
40 | // Create new Fragment
41 | RationaleDialogFragment dialogFragment = new RationaleDialogFragment();
42 |
43 | // Initialize configuration as arguments
44 | RationaleDialogConfig config = new RationaleDialogConfig(
45 | positiveButton, negativeButton, rationaleMsg, theme, requestCode, list, permissions);
46 | dialogFragment.setArguments(config.toBundle());
47 |
48 | return dialogFragment;
49 | }
50 |
51 | @Override
52 | public void onAttach(Context context) {
53 | super.onAttach(context);
54 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && getParentFragment() != null) {
55 | if (getParentFragment() instanceof EasyPermissions.PermissionCallbacks) {
56 | mPermissionCallbacks = (EasyPermissions.PermissionCallbacks) getParentFragment();
57 | }
58 | if (getParentFragment() instanceof EasyPermissions.RationaleCallbacks) {
59 | mRationaleCallbacks = (EasyPermissions.RationaleCallbacks) getParentFragment();
60 | }
61 |
62 | }
63 |
64 | if (context instanceof EasyPermissions.PermissionCallbacks) {
65 | mPermissionCallbacks = (EasyPermissions.PermissionCallbacks) context;
66 | }
67 |
68 | if (context instanceof EasyPermissions.RationaleCallbacks) {
69 | mRationaleCallbacks = (EasyPermissions.RationaleCallbacks) context;
70 | }
71 | }
72 |
73 | @Override
74 | public void onSaveInstanceState(Bundle outState) {
75 | mStateSaved = true;
76 | super.onSaveInstanceState(outState);
77 | }
78 |
79 | /**
80 | * Version of {@link #show(FragmentManager, String)} that no-ops when an IllegalStateException
81 | * would otherwise occur.
82 | */
83 | public void showAllowingStateLoss(FragmentManager manager, String tag) {
84 | // API 26 added this convenient method
85 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
86 | if (manager.isStateSaved()) {
87 | return;
88 | }
89 | }
90 |
91 | if (mStateSaved) {
92 | return;
93 | }
94 |
95 | show(manager, tag);
96 | }
97 |
98 | @Override
99 | public void onDetach() {
100 | super.onDetach();
101 | mPermissionCallbacks = null;
102 | }
103 |
104 | @NonNull
105 | @Override
106 | public Dialog onCreateDialog(Bundle savedInstanceState) {
107 | // Rationale dialog should not be cancelable
108 | setCancelable(false);
109 |
110 | // Get config from arguments, create click listener
111 | RationaleDialogConfig config = new RationaleDialogConfig(getArguments());
112 | // RationaleDialogClickListener clickListener =
113 | // new RationaleDialogClickListener(this, config, mPermissionCallbacks, mRationaleCallbacks);
114 | RationaleClickListener clickListener =
115 | new RationaleClickListener(this, config, mPermissionCallbacks, mRationaleCallbacks);
116 | // Create an AlertDialog
117 | return config.createFrameworkDialog(getActivity(), clickListener);
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/RationaleDialogFragmentCompat.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.os.Bundle;
6 |
7 | import androidx.annotation.NonNull;
8 | import androidx.annotation.RestrictTo;
9 | import androidx.annotation.StyleRes;
10 | import androidx.appcompat.app.AppCompatDialogFragment;
11 | import androidx.fragment.app.FragmentManager;
12 |
13 | import com.db.policylib.PermissionPolicy;
14 |
15 | import java.util.List;
16 |
17 | /**
18 | * {@link AppCompatDialogFragment} to display rationale for permission requests when the request
19 | * comes from a Fragment or Activity that can host a Fragment.
20 | */
21 | @RestrictTo(RestrictTo.Scope.LIBRARY)
22 | public class RationaleDialogFragmentCompat extends AppCompatDialogFragment {
23 |
24 | public static final String TAG = "RationaleDialogFragmentCompat";
25 |
26 | private EasyPermissions.PermissionCallbacks mPermissionCallbacks;
27 | private EasyPermissions.RationaleCallbacks mRationaleCallbacks;
28 |
29 | public static RationaleDialogFragmentCompat newInstance(
30 | @NonNull String rationaleMsg,
31 | @NonNull String positiveButton,
32 | @NonNull String negativeButton,
33 | @StyleRes int theme,
34 | int requestCode, List list,
35 | @NonNull String[] permissions) {
36 |
37 | // Create new Fragment
38 | RationaleDialogFragmentCompat dialogFragment = new RationaleDialogFragmentCompat();
39 |
40 | // Initialize configuration as arguments
41 | RationaleDialogConfig config = new RationaleDialogConfig(
42 | positiveButton, negativeButton, rationaleMsg, theme, requestCode, list, permissions);
43 | dialogFragment.setArguments(config.toBundle());
44 |
45 | return dialogFragment;
46 | }
47 |
48 | /**
49 | * Version of {@link #show(FragmentManager, String)} that no-ops when an IllegalStateException
50 | * would otherwise occur.
51 | */
52 | public void showAllowingStateLoss(FragmentManager manager, String tag) {
53 | if (manager.isStateSaved()) {
54 | return;
55 | }
56 |
57 | show(manager, tag);
58 | }
59 |
60 | @Override
61 | public void onAttach(Context context) {
62 | super.onAttach(context);
63 | if (getParentFragment() != null) {
64 | if (getParentFragment() instanceof EasyPermissions.PermissionCallbacks) {
65 | mPermissionCallbacks = (EasyPermissions.PermissionCallbacks) getParentFragment();
66 | }
67 | if (getParentFragment() instanceof EasyPermissions.RationaleCallbacks) {
68 | mRationaleCallbacks = (EasyPermissions.RationaleCallbacks) getParentFragment();
69 | }
70 | }
71 |
72 | if (context instanceof EasyPermissions.PermissionCallbacks) {
73 | mPermissionCallbacks = (EasyPermissions.PermissionCallbacks) context;
74 | }
75 |
76 | if (context instanceof EasyPermissions.RationaleCallbacks) {
77 | mRationaleCallbacks = (EasyPermissions.RationaleCallbacks) context;
78 | }
79 | }
80 |
81 | @Override
82 | public void onDetach() {
83 | super.onDetach();
84 | mPermissionCallbacks = null;
85 | mRationaleCallbacks = null;
86 | }
87 |
88 | @NonNull
89 | @Override
90 | public Dialog onCreateDialog(Bundle savedInstanceState) {
91 | // Rationale dialog should not be cancelable
92 | setCancelable(false);
93 |
94 | // Get config from arguments, create click listener
95 | RationaleDialogConfig config = new RationaleDialogConfig(getArguments());
96 | // RationaleDialogClickListener clickListener =
97 | // new RationaleDialogClickListener(this, config, mPermissionCallbacks, mRationaleCallbacks);
98 | RationaleClickListener clickListener =
99 | new RationaleClickListener(this, config, mPermissionCallbacks, mRationaleCallbacks);
100 | // Create an AlertDialog
101 | return config.createSupportDialog(getContext(), clickListener);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/helper/ActivityPermissionHelper.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions.helper;
2 |
3 | import android.app.Activity;
4 | import android.app.Fragment;
5 | import android.app.FragmentManager;
6 | import android.content.Context;
7 | import android.util.Log;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.annotation.StyleRes;
11 | import androidx.core.app.ActivityCompat;
12 |
13 | import com.db.policylib.PermissionPolicy;
14 |
15 | import java.util.List;
16 |
17 | import pub.devrel.easypermissions.RationaleDialogFragment;
18 |
19 | /**
20 | * Permissions helper for {@link Activity}.
21 | */
22 | class ActivityPermissionHelper extends PermissionHelper {
23 | private static final String TAG = "ActPermissionHelper";
24 |
25 | public ActivityPermissionHelper(Activity host) {
26 | super(host);
27 | }
28 |
29 | @Override
30 | public void directRequestPermissions(int requestCode, @NonNull String... perms) {
31 | ActivityCompat.requestPermissions(getHost(), perms, requestCode);
32 | }
33 |
34 | @Override
35 | public boolean shouldShowRequestPermissionRationale(@NonNull String perm) {
36 | return ActivityCompat.shouldShowRequestPermissionRationale(getHost(), perm);
37 | }
38 |
39 | @Override
40 | public Context getContext() {
41 | return getHost();
42 | }
43 |
44 | @Override
45 | public void showRequestPermissionRationale(@NonNull String rationale,
46 | @NonNull String positiveButton,
47 | @NonNull String negativeButton,
48 | @StyleRes int theme,
49 | int requestCode, List list,
50 | @NonNull String... perms) {
51 | FragmentManager fm = getHost().getFragmentManager();
52 | // Check if fragment is already showing
53 | Fragment fragment = fm.findFragmentByTag(RationaleDialogFragment.TAG);
54 | if (fragment instanceof RationaleDialogFragment) {
55 | Log.d(TAG, "Found existing fragment, not showing rationale.");
56 | return;
57 | }
58 |
59 | RationaleDialogFragment
60 | .newInstance(positiveButton, negativeButton, rationale, theme, requestCode, list, perms)
61 | .showAllowingStateLoss(fm, RationaleDialogFragment.TAG);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/helper/AppCompatActivityPermissionsHelper.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions.helper;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.appcompat.app.AppCompatActivity;
7 | import androidx.core.app.ActivityCompat;
8 | import androidx.fragment.app.FragmentManager;
9 |
10 | /**
11 | * Permissions helper for {@link AppCompatActivity}.
12 | */
13 | class AppCompatActivityPermissionsHelper extends BaseSupportPermissionsHelper {
14 |
15 | public AppCompatActivityPermissionsHelper(AppCompatActivity host) {
16 | super(host);
17 | }
18 |
19 | @Override
20 | public FragmentManager getSupportFragmentManager() {
21 | return getHost().getSupportFragmentManager();
22 | }
23 |
24 | @Override
25 | public void directRequestPermissions(int requestCode, @NonNull String... perms) {
26 | ActivityCompat.requestPermissions(getHost(), perms, requestCode);
27 | }
28 |
29 | @Override
30 | public boolean shouldShowRequestPermissionRationale(@NonNull String perm) {
31 | return ActivityCompat.shouldShowRequestPermissionRationale(getHost(), perm);
32 | }
33 |
34 | @Override
35 | public Context getContext() {
36 | return getHost();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/helper/BaseSupportPermissionsHelper.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions.helper;
2 |
3 | import android.util.Log;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.annotation.StyleRes;
7 | import androidx.fragment.app.Fragment;
8 | import androidx.fragment.app.FragmentManager;
9 |
10 | import com.db.policylib.PermissionPolicy;
11 |
12 | import java.util.List;
13 |
14 | import pub.devrel.easypermissions.RationaleDialogFragmentCompat;
15 |
16 | /**
17 | * Implementation of {@link PermissionHelper} for Support Library host classes.
18 | */
19 | public abstract class BaseSupportPermissionsHelper extends PermissionHelper {
20 |
21 | private static final String TAG = "BSPermissionsHelper";
22 |
23 | public BaseSupportPermissionsHelper(@NonNull T host) {
24 | super(host);
25 | }
26 |
27 | public abstract FragmentManager getSupportFragmentManager();
28 |
29 | @Override
30 | public void showRequestPermissionRationale(@NonNull String rationale,
31 | @NonNull String positiveButton,
32 | @NonNull String negativeButton,
33 | @StyleRes int theme,
34 | int requestCode, List list,
35 | @NonNull String... perms) {
36 |
37 | FragmentManager fm = getSupportFragmentManager();
38 |
39 | // Check if fragment is already showing
40 | Fragment fragment = fm.findFragmentByTag(RationaleDialogFragmentCompat.TAG);
41 | if (fragment instanceof RationaleDialogFragmentCompat) {
42 | Log.d(TAG, "Found existing fragment, not showing rationale.");
43 | return;
44 | }
45 |
46 | RationaleDialogFragmentCompat
47 | .newInstance(rationale, positiveButton, negativeButton, theme, requestCode, list, perms)
48 | .showAllowingStateLoss(fm, RationaleDialogFragmentCompat.TAG);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/helper/LowApiPermissionsHelper.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions.helper;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 |
6 | import androidx.annotation.NonNull;
7 | import androidx.annotation.StyleRes;
8 | import androidx.fragment.app.Fragment;
9 |
10 | import com.db.policylib.PermissionPolicy;
11 |
12 | import java.util.List;
13 |
14 | /**
15 | * Permissions helper for apps built against API < 23, which do not need runtime permissions.
16 | */
17 | class LowApiPermissionsHelper extends PermissionHelper {
18 | public LowApiPermissionsHelper(@NonNull T host) {
19 | super(host);
20 | }
21 |
22 | @Override
23 | public void directRequestPermissions(int requestCode, @NonNull String... perms) {
24 | throw new IllegalStateException("Should never be requesting permissions on API < 23!");
25 | }
26 |
27 | @Override
28 | public boolean shouldShowRequestPermissionRationale(@NonNull String perm) {
29 | return false;
30 | }
31 |
32 | @Override
33 | public void showRequestPermissionRationale(@NonNull String rationale,
34 | @NonNull String positiveButton,
35 | @NonNull String negativeButton,
36 | @StyleRes int theme,
37 | int requestCode, List list,
38 | @NonNull String... perms) {
39 | throw new IllegalStateException("Should never be requesting permissions on API < 23!");
40 | }
41 |
42 | @Override
43 | public Context getContext() {
44 | if (getHost() instanceof Activity) {
45 | return (Context) getHost();
46 | } else if (getHost() instanceof Fragment) {
47 | return ((Fragment) getHost()).getContext();
48 | } else {
49 | throw new IllegalStateException("Unknown host: " + getHost());
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/helper/PermissionHelper.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions.helper;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.os.Build;
6 |
7 | import androidx.annotation.NonNull;
8 | import androidx.annotation.StyleRes;
9 | import androidx.appcompat.app.AppCompatActivity;
10 | import androidx.fragment.app.Fragment;
11 |
12 | import com.db.policylib.PermissionPolicy;
13 | import com.db.policylib.Policy;
14 |
15 | import java.util.List;
16 |
17 | /**
18 | * Delegate class to make permission calls based on the 'host' (Fragment, Activity, etc).
19 | */
20 | public abstract class PermissionHelper {
21 |
22 | private T mHost;
23 |
24 | @NonNull
25 | public static PermissionHelper extends Activity> newInstance(Activity host) {
26 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
27 | return new LowApiPermissionsHelper<>(host);
28 | }
29 |
30 | if (host instanceof AppCompatActivity)
31 | return new AppCompatActivityPermissionsHelper((AppCompatActivity) host);
32 | else {
33 | return new ActivityPermissionHelper(host);
34 | }
35 | }
36 |
37 | @NonNull
38 | public static PermissionHelper newInstance(Fragment host) {
39 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
40 | return new LowApiPermissionsHelper<>(host);
41 | }
42 |
43 | return new SupportFragmentPermissionHelper(host);
44 | }
45 |
46 | // ============================================================================
47 | // Public concrete methods
48 | // ============================================================================
49 |
50 | public PermissionHelper(@NonNull T host) {
51 | mHost = host;
52 | }
53 |
54 | private boolean shouldShowRationale(@NonNull String... perms) {
55 | for (String perm : perms) {
56 | if (shouldShowRequestPermissionRationale(perm)) {
57 | return true;
58 | }
59 | }
60 | return false;
61 | }
62 |
63 | public void requestPermissions(@NonNull String rationale,
64 | @NonNull String positiveButton,
65 | @NonNull String negativeButton,
66 | @StyleRes int theme,
67 | int requestCode, List list,
68 | @NonNull String... perms) {
69 | if (shouldShowRationale(perms) || !Policy.getInstance().getStringList(getHostContext(), perms)) {// !TextUtils.isEmpty(rationale)
70 | showRequestPermissionRationale(
71 | rationale, positiveButton, negativeButton, theme, requestCode, list, perms);
72 | } else {
73 | directRequestPermissions(requestCode, perms);
74 | }
75 | }
76 |
77 | public boolean somePermissionPermanentlyDenied(@NonNull List perms) {
78 | for (String deniedPermission : perms) {
79 | if (permissionPermanentlyDenied(deniedPermission)) {
80 | return true;
81 | }
82 | }
83 |
84 | return false;
85 | }
86 |
87 | public boolean permissionPermanentlyDenied(@NonNull String perms) {
88 | return !shouldShowRequestPermissionRationale(perms);
89 | }
90 |
91 | public boolean somePermissionDenied(@NonNull String... perms) {
92 | return shouldShowRationale(perms);
93 | }
94 |
95 | @NonNull
96 | public T getHost() {
97 | return mHost;
98 | }
99 |
100 | public Context getHostContext() {
101 | if (getHost() instanceof Activity) {
102 | return (Context) getHost();
103 | } else if (getHost() instanceof Fragment) {
104 | return ((Fragment) getHost()).getContext();
105 | } else {
106 | throw new IllegalStateException("Unknown host: " + getHost());
107 | }
108 | }
109 |
110 | // ============================================================================
111 | // Public abstract methods
112 | // ============================================================================
113 |
114 | public abstract void directRequestPermissions(int requestCode, @NonNull String... perms);
115 |
116 | public abstract boolean shouldShowRequestPermissionRationale(@NonNull String perm);
117 |
118 | public abstract void showRequestPermissionRationale(@NonNull String rationale,
119 | @NonNull String positiveButton,
120 | @NonNull String negativeButton,
121 | @StyleRes int theme,
122 | int requestCode, List list,
123 | @NonNull String... perms);
124 |
125 | public abstract Context getContext();
126 |
127 | }
128 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/helper/SupportFragmentPermissionHelper.java:
--------------------------------------------------------------------------------
1 | package pub.devrel.easypermissions.helper;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.fragment.app.Fragment;
7 | import androidx.fragment.app.FragmentManager;
8 |
9 | /**
10 | * Permissions helper for {@link Fragment} from the support library.
11 | */
12 | class SupportFragmentPermissionHelper extends BaseSupportPermissionsHelper {
13 |
14 | public SupportFragmentPermissionHelper(@NonNull Fragment host) {
15 | super(host);
16 | }
17 |
18 | @Override
19 | public FragmentManager getSupportFragmentManager() {
20 | return getHost().getChildFragmentManager();
21 | }
22 |
23 | @Override
24 | public void directRequestPermissions(int requestCode, @NonNull String... perms) {
25 | getHost().requestPermissions(perms, requestCode);
26 | }
27 |
28 | @Override
29 | public boolean shouldShowRequestPermissionRationale(@NonNull String perm) {
30 | return getHost().shouldShowRequestPermissionRationale(perm);
31 | }
32 |
33 | @Override
34 | public Context getContext() {
35 | return getHost().getActivity();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/policylib/src/main/java/pub/devrel/easypermissions/helper/package-info.java:
--------------------------------------------------------------------------------
1 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
2 | package pub.devrel.easypermissions.helper;
3 |
4 | import androidx.annotation.RestrictTo;
--------------------------------------------------------------------------------
/policylib/src/main/res/drawable/btn_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/policylib/src/main/res/drawable/btn_pressed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/policylib/src/main/res/drawable/btn_rule.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/policylib/src/main/res/drawable/btn_rule_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/policylib/src/main/res/drawable/btn_rule_pressed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/policylib/src/main/res/drawable/btn_rule_right_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/policylib/src/main/res/drawable/btn_rule_right_pressed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/policylib/src/main/res/drawable/btn_rule_right_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/policylib/src/main/res/drawable/btn_rule_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/policylib/src/main/res/drawable/btn_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/policylib/src/main/res/layout/item_policy.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
21 |
22 |
29 |
30 |
38 |
39 |
--------------------------------------------------------------------------------
/policylib/src/main/res/layout/layout_policy.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
21 |
22 |
35 |
36 |
42 |
43 |
47 |
48 |
54 |
55 |
67 |
68 |
72 |
73 |
85 |
86 |
87 |
97 |
--------------------------------------------------------------------------------
/policylib/src/main/res/layout/layout_rule.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
20 |
21 |
25 |
26 |
39 |
40 |
44 |
45 |
49 |
50 |
62 |
63 |
67 |
68 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/policylib/src/main/res/layout/layout_update.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
20 |
21 |
25 |
26 |
39 |
40 |
44 |
45 |
50 |
51 |
63 |
64 |
68 |
69 |
81 |
82 |
83 |
94 |
95 |
--------------------------------------------------------------------------------
/policylib/src/main/res/mipmap-xhdpi/icon_camera_permission.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jaychou2012/PolicyLib/d894e4ce3ffbe82b06624c8d731df0833ef51ca9/policylib/src/main/res/mipmap-xhdpi/icon_camera_permission.png
--------------------------------------------------------------------------------
/policylib/src/main/res/mipmap-xhdpi/icon_record_audio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jaychou2012/PolicyLib/d894e4ce3ffbe82b06624c8d731df0833ef51ca9/policylib/src/main/res/mipmap-xhdpi/icon_record_audio.png
--------------------------------------------------------------------------------
/policylib/src/main/res/mipmap-xhdpi/icon_storage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jaychou2012/PolicyLib/d894e4ce3ffbe82b06624c8d731df0833ef51ca9/policylib/src/main/res/mipmap-xhdpi/icon_storage.png
--------------------------------------------------------------------------------
/policylib/src/main/res/mipmap-xhdpi/icon_tel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jaychou2012/PolicyLib/d894e4ce3ffbe82b06624c8d731df0833ef51ca9/policylib/src/main/res/mipmap-xhdpi/icon_tel.png
--------------------------------------------------------------------------------
/policylib/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 | #D9D9D9
7 | #cccccc
8 | #3F51B5
9 | #ff808080
10 |
11 |
--------------------------------------------------------------------------------
/policylib/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | PolicyLib
3 | This app may not work correctly without the requested permissions.
4 |
5 | This app may not work correctly without the requested permissions.
6 | Open the app settings screen to modify app permissions.
7 |
8 | Permissions Required
9 |
--------------------------------------------------------------------------------
/policylib/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
18 |
19 |
27 |
28 |
--------------------------------------------------------------------------------
/policylib/src/main/res/xml/file_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
10 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/policylib/src/main/res/xml/net_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/policylib/src/test/java/com/db/policylib/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.db.policylib;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':policylib'
2 | rootProject.name='PolicyLibDemo'
3 |
--------------------------------------------------------------------------------