Skip to content

Instantly share code, notes, and snippets.

@techyourchance
Last active January 11, 2022 08:01
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save techyourchance/18f84ec1a04c82c32007b2b231277ca7 to your computer and use it in GitHub Desktop.
Save techyourchance/18f84ec1a04c82c32007b2b231277ca7 to your computer and use it in GitHub Desktop.
Abstraction for clean management of runtime permissions in Android applications
public enum MyPermission {
// declare runtime permissions specific to your app here (don't keep unused ones)
READ_PHONE_STATE(Manifest.permission.READ_PHONE_STATE),
FINE_LOCATION(Manifest.permission.ACCESS_FINE_LOCATION);
public static MyPermission fromAndroidPermission(String androidPermission) {
for (MyPermission permission : MyPermission.values()) {
if (permission.getAndroidPermission().equals(androidPermission)) {
return permission;
}
}
throw new RuntimeException("Android permission not supported yet: " + androidPermission);
}
private final String mAndroidPermission;
private MyPermission(String androidPermission) {
mAndroidPermission = androidPermission;
}
public String getAndroidPermission() {
return mAndroidPermission;
}
}
/**
* Instances of this class must be Activity-scoped. In other words, a single instance of
* this class MUST be shared among all the clients within the hierarchy of a single Activity.
* Read more here: https://www.techyourchance.com/runtime-permissions-android
*/
@UiThread
public class PermissionsHelper extends Observable<PermissionsHelper.Listener> {
public interface Listener {
void onRequestPermissionsResult(int requestCode, PermissionsResult result);
void onPermissionsRequestCancelled(int requestCode);
}
public static class PermissionsResult {
public final List<MyPermission> granted;
public final List<MyPermission> denied;
public final List<MyPermission> deniedDoNotAskAgain;
public PermissionsResult(List<MyPermission> granted, List<MyPermission> denied, List<MyPermission> deniedDoNotAskAgain) {
this.granted = granted;
this.denied = denied;
this.deniedDoNotAskAgain = deniedDoNotAskAgain;
}
}
private final Activity mActivity;
public PermissionsHelper(Activity activity) {
mActivity = activity;
}
public boolean hasPermission(MyPermission permission) {
return ContextCompat.checkSelfPermission(mActivity, permission.getAndroidPermission()) == PackageManager.PERMISSION_GRANTED;
}
public boolean hasAllPermissions(MyPermission[] permissions) {
for (MyPermission permission : permissions) {
if (ContextCompat.checkSelfPermission(mActivity, permission.getAndroidPermission()) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
public void requestPermission(MyPermission permission, int requestCode) {
ActivityCompat.requestPermissions(mActivity, new String[] { permission.getAndroidPermission() }, requestCode);
}
public void requestAllPermissions(MyPermission[] permissions, int requestCode) {
String[] androidPermissions = new String[permissions.length];
for (int i = 0; i < permissions.length; i++) {
androidPermissions[i] = permissions[i].getAndroidPermission();
}
ActivityCompat.requestPermissions(mActivity, androidPermissions, requestCode);
}
public void onRequestPermissionsResult(int requestCode, @NonNull String[] androidPermissions, @NonNull int[] grantResults) {
if (androidPermissions.length == 0 || grantResults.length == 0) {
notifyPermissionsRequestCancelled(requestCode);
}
List<MyPermission> grantedPermissions = new LinkedList<>();
List<MyPermission> deniedPermissions = new LinkedList<>();
List<MyPermission> deniedAndDoNotAskAgainPermissions = new LinkedList<>();
String androidPermission;
MyPermission permission;
for (int i = 0; i < androidPermissions.length; i++) {
androidPermission = androidPermissions[i];
permission = MyPermission.fromAndroidPermission(androidPermission);
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
grantedPermissions.add(permission);
} else if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, androidPermission)) {
deniedPermissions.add(permission);
} else {
deniedAndDoNotAskAgainPermissions.add(permission);
}
}
PermissionsResult result = new PermissionsResult(grantedPermissions, deniedPermissions, deniedAndDoNotAskAgainPermissions);
notifyPermissionsResult(requestCode, result);
}
private void notifyPermissionsResult(int requestCode, PermissionsResult permissionsResult) {
for (Listener listener : getListeners()) {
listener.onRequestPermissionsResult(requestCode, permissionsResult);
}
}
private void notifyPermissionsRequestCancelled(int requestCode) {
for (Listener listener : getListeners()) {
listener.onPermissionsRequestCancelled(requestCode);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment