|
|
@ -14,30 +14,53 @@ import java.util.List; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Copyright 8/22/2015 Anthony Restaino |
|
|
|
* A class to help you manage your permissions |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public final class PermissionsManager { |
|
|
|
public final class PermissionsManager { |
|
|
|
|
|
|
|
|
|
|
|
private static PermissionsManager mInstance; |
|
|
|
private final static PermissionsManager INSTANCE = new PermissionsManager(); |
|
|
|
private final Set<String> mPendingRequests = new HashSet<>(); |
|
|
|
private final Set<String> mPendingRequests = new HashSet<>(1); |
|
|
|
private final List<PermissionResult> mPendingActions = new ArrayList<>(); |
|
|
|
private final List<PermissionResult> mPendingActions = new ArrayList<>(1); |
|
|
|
|
|
|
|
|
|
|
|
public static PermissionsManager getInstance() { |
|
|
|
public static PermissionsManager getInstance() { |
|
|
|
if (mInstance == null) { |
|
|
|
return INSTANCE; |
|
|
|
mInstance = new PermissionsManager(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return mInstance; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void addPendingAction(@NonNull String[] permissions, @Nullable PermissionResult result) { |
|
|
|
/** |
|
|
|
|
|
|
|
* This method adds the {@link PermissionResult} to the current list |
|
|
|
|
|
|
|
* of pending actions that will be completed when the permissions are |
|
|
|
|
|
|
|
* received. The list of permissions passed to this method are registered |
|
|
|
|
|
|
|
* in the PermissionResult object so that it will be notified of changes |
|
|
|
|
|
|
|
* made to these permissions. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param permissions the required permissions for the result to be executed |
|
|
|
|
|
|
|
* @param result the result to add to the current list of pending actions |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private synchronized void addPendingAction(@NonNull String[] permissions, @Nullable PermissionResult result) { |
|
|
|
if (result == null) { |
|
|
|
if (result == null) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
result.addPermissions(permissions); |
|
|
|
result.registerPermissions(permissions); |
|
|
|
mPendingActions.add(result); |
|
|
|
mPendingActions.add(result); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void requestPermissionsIfNecessary(@Nullable Activity activity, @NonNull String[] permissions, @Nullable PermissionResult result) { |
|
|
|
/** |
|
|
|
|
|
|
|
* This method should be used to execute a {@link PermissionResult} for the array |
|
|
|
|
|
|
|
* of permissions passed to this method. This method will request the permissions if |
|
|
|
|
|
|
|
* they need to be requested (i.e. we don't have permission yet) and will add the |
|
|
|
|
|
|
|
* PermissionResult to the queue to be notified of permissions being granted or |
|
|
|
|
|
|
|
* denied. In the case of pre-Android Marshmallow, permissions will be granted immediately. |
|
|
|
|
|
|
|
* The Activity variable is nullable, but if it is null, the method will fail to execute. |
|
|
|
|
|
|
|
* This is only nullable as a courtesy for Fragments where getActivity() may yeild null |
|
|
|
|
|
|
|
* if the Fragment is not currently added to its parent Activity. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param activity the activity necessary to request the permissions |
|
|
|
|
|
|
|
* @param permissions the list of permissions to request for the {@link PermissionResult} |
|
|
|
|
|
|
|
* @param result the PermissionResult to notify when the permissions are granted or denied |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public synchronized void requestPermissionsIfNecessaryForResult(@Nullable Activity activity, |
|
|
|
|
|
|
|
@NonNull String[] permissions, |
|
|
|
|
|
|
|
@Nullable PermissionResult result) { |
|
|
|
if (activity == null) { |
|
|
|
if (activity == null) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -50,7 +73,7 @@ public final class PermissionsManager { |
|
|
|
} |
|
|
|
} |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
List<String> permList = new ArrayList<>(); |
|
|
|
List<String> permList = new ArrayList<>(1); |
|
|
|
for (String perm : permissions) { |
|
|
|
for (String perm : permissions) { |
|
|
|
if (ActivityCompat.checkSelfPermission(activity, perm) != PackageManager.PERMISSION_GRANTED) { |
|
|
|
if (ActivityCompat.checkSelfPermission(activity, perm) != PackageManager.PERMISSION_GRANTED) { |
|
|
|
if (!mPendingRequests.contains(perm)) { |
|
|
|
if (!mPendingRequests.contains(perm)) { |
|
|
@ -70,20 +93,16 @@ public final class PermissionsManager { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static boolean checkPermissions(Activity activity, @NonNull String[] permissions) { |
|
|
|
/** |
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { |
|
|
|
* This method notifies the PermissionsManager that the permissions have change. It should |
|
|
|
return true; |
|
|
|
* be called from the Activity callback onRequestPermissionsResult() with the variables |
|
|
|
} else if (activity == null) { |
|
|
|
* passed to that method. It will notify all the pending PermissionResult objects currently |
|
|
|
return false; |
|
|
|
* in the queue, and will remove the permissions request from the list of pending requests. |
|
|
|
} |
|
|
|
* |
|
|
|
boolean permissionsNecessary = true; |
|
|
|
* @param permissions the permissions that have changed |
|
|
|
for (String perm : permissions) { |
|
|
|
* @param results the values for each permission |
|
|
|
permissionsNecessary &= activity.checkSelfPermission(perm) == PackageManager.PERMISSION_GRANTED; |
|
|
|
*/ |
|
|
|
} |
|
|
|
public synchronized void notifyPermissionsChange(@NonNull String[] permissions, @NonNull int[] results) { |
|
|
|
return permissionsNecessary; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void notifyPermissionsChange(@NonNull String[] permissions, @NonNull int[] results) { |
|
|
|
|
|
|
|
int size = permissions.length; |
|
|
|
int size = permissions.length; |
|
|
|
if (results.length < size) { |
|
|
|
if (results.length < size) { |
|
|
|
size = results.length; |
|
|
|
size = results.length; |
|
|
@ -96,15 +115,33 @@ public final class PermissionsManager { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* This abstract class should be used to create an if/else action that the PermissionsManager |
|
|
|
|
|
|
|
* can execute when the permissions you request are granted or denied. Simple use involves |
|
|
|
|
|
|
|
* creating an anonymous instance of it and passing that instance to the |
|
|
|
|
|
|
|
* requestPermissionsIfNecessaryForResult method. The result will be sent back to you as |
|
|
|
|
|
|
|
* either onGranted (all permissions have been granted), or onDenied (a required permission |
|
|
|
|
|
|
|
* has been denied). Ideally you put your functionality in the onGranted method and notify |
|
|
|
|
|
|
|
* the user what won't work in the onDenied method. |
|
|
|
|
|
|
|
*/ |
|
|
|
public static abstract class PermissionResult { |
|
|
|
public static abstract class PermissionResult { |
|
|
|
|
|
|
|
|
|
|
|
private Set<String> mPermissions = new HashSet<>(); |
|
|
|
private final Set<String> mPermissions = new HashSet<>(1); |
|
|
|
|
|
|
|
|
|
|
|
public abstract void onGranted(); |
|
|
|
public abstract void onGranted(); |
|
|
|
|
|
|
|
|
|
|
|
public abstract void onDenied(String permission); |
|
|
|
public abstract void onDenied(String permission); |
|
|
|
|
|
|
|
|
|
|
|
public void onResult(String permission, int result) { |
|
|
|
/** |
|
|
|
|
|
|
|
* This method is called when a particular permission has changed. |
|
|
|
|
|
|
|
* This method will be called for all permissions, so this method determines |
|
|
|
|
|
|
|
* if the permission affects the state or not and whether it can proceed with |
|
|
|
|
|
|
|
* calling onGranted or if onDenied should be called. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param permission the permission that changed |
|
|
|
|
|
|
|
* @param result the result for that permission |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public synchronized final void onResult(String permission, int result) { |
|
|
|
if (result == PackageManager.PERMISSION_GRANTED) { |
|
|
|
if (result == PackageManager.PERMISSION_GRANTED) { |
|
|
|
mPermissions.remove(permission); |
|
|
|
mPermissions.remove(permission); |
|
|
|
if (mPermissions.isEmpty()) { |
|
|
|
if (mPermissions.isEmpty()) { |
|
|
@ -115,7 +152,14 @@ public final class PermissionsManager { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void addPermissions(@NonNull String[] perms) { |
|
|
|
/** |
|
|
|
|
|
|
|
* This method registers the PermissionResult object for the specified permissions |
|
|
|
|
|
|
|
* so that it will know which permissions to look for changes to. The PermissionResult |
|
|
|
|
|
|
|
* will then know to look out for changes to these permissions. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param perms the permissions to listen for |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public synchronized final void registerPermissions(@NonNull String[] perms) { |
|
|
|
Collections.addAll(mPermissions, perms); |
|
|
|
Collections.addAll(mPermissions, perms); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|