Reactive Android Permissions in a breeze

I’m a big fan of reactive programming. The more I have been using it throughout the years the more I have wanted to apply it to everything.

Back in the marshmallow days when Android Permissions were introduced Thomas Bruyelle was working on writing an RxJava API for Android Permissions. I’ve liked it very much and kept using it. During that time RxJava 2 has gotten stable and was released. I ported the library over to RxJava 2.

With time things then went into different directions:

  • You could no longer use the library without an Activity which was a big negative point on my side
  • I felt and still feel like the API is very verbose and offers a lot of things — which you might use but probably won’t
  • Proper support for Single when requesting a permission was and still is missing
  • I needed to know whether the don’t ask me again was clicked or not. I tried implementing it but we had different opinions — which is fine. Being objective and hard in open source projects is very important

Forking

All of those points got me thinking and hence I forked the library, rewrote a few things and now the API looks like this:

public interface RxPermission {
/** Requests a single permission if not granted. */
Single<Permission> request(String permission);
 /** Requests multiple permissions if not already granted. */
Observable<Permission> requestEach(String… permissions);
 /** Returns true when the permission is granted. */
boolean isGranted(String permission);
 /** Returns true when the permission is revoked by a policy. */
boolean isRevokedByPolicy(String permission);
}

This should fit the need of most cases where you need to deal with permissions. The Permission class contains the name and the state that returns one of the following. GRANTED, DENIED, DENIED_NOT_SHOWN or REVOKED_BY_POLICY.

Getting a real instance of the RxPermission interface that will display the dialog is a one-liner RealRxPermission.getInstance(application).

Out of the box testing support

To ease testing, I created a MockRxPermission class that also implements the RxPermission interface and lets you pass in stub Permission objects.

RxPermission rxPermission = new MockRxPermission(
Permission.denied(Manifest.permission.CAMERA),
Permission.granted(Manifest.permission.ACCOUNT_MANAGER)
);

Here are the other factory methods on Permission:

/** This will create a granted Camera Permission. */
Permission.granted(Manifest.permission.CAMERA)
/** This will create a denied Camera Permission. */
Permission.denied(Manifest.permission.CAMERA)
/** This will create a denied not shown Camera Permission. */
Permission.deniedNotShown(Manifest.permission.CAMERA)
/** This will create a policy revoked Camera Permission. */
Permission.revokedByPolicy(Manifest.permission.CAMERA)

Conclusion

This post should in no way convey as ranting about the original library. I’m very grateful for it. I learned quite a few things from it. I just decided that it does not fit my personal needs anymore and hence my version of RxPermission was born.

https://github.com/vanniktech/RxPermission

implementation 'com.vanniktech:rxpermission:0.3.0'

Let me know what you think.