Permissions, RxJava and lifecycle
This article will demonstrate how to delegate permission handling to a designated class whose instance in retrieved using dependency retrieval with Kodein.
I will show how to implement and then call a fuction that takes in a list of permissions to request. Each such permission will be accompanied with one action that will be called when the permission has been granted, and one that will be called whet it has been denied.
Configuration of dependency retrieval with Kodein has been already described in this blog in the article called ‘Testing with dependency retrieval’.
Presented herein permission-handling code has been used in the project Wiktor-Navigator.
Structure of the request
The class containing the request contains the name of the request, the action called when it has been granted, the action called when it has beed denied, and doesnt’t contain any fuction. By default both of these actions are empty:
Requesting the permissions
Permissions are requested by calling a global extention function called on the Fragment
. Because I use Navigation Architecture component almost all of GUI is implementet in Fragment
s as opposed to Activity
s, but one could write a similar extention function for Activity
as well:
The call permissions
automatically retrieves an instance of the permission-handling class, whose Kodein binding is created in the module in this line:
It is then retrieved by this global property:
This is the code that actually requests the permissions and subscribes the responses using RxJava:
It uses lifecycle
to automatically dispose the subscriptions when activity ends. Making lifecycle-aware subscribtions has been described in this blog in the article called ‘Lifecycle-aware Rx subscriptions’.
CAUTION: Do not use the method ActivityCompat.requestPermissions()
. Although you can adapt the above code to successfully use this method to request permissions, if you do this instead of calling the method requestPermissions
directly on Fragment
, only the callback onRequestPermissionsResult()
inside the Activity
(not Fragment
) will be called.
In the Fragment
This is the code in the Fragment
that requests Location permission, passing to the request the actions that will be called when it is granted or denied:
If the permission is denied, a snackbar will be shown, prompting the user again to grant the permission. When the user chooses to automatically deny the permission each time, this snackbar will just continue to show up, suggesting to the user that this permission is mandatory for the application to function.
Handling responses
Handling the response begins in the Fragment
:
It retrieves an instance of the permissions-handling class and passes the results to it. The actual permission-handling code:
It just calls onNext
on the appropriate RxJava’s Subject
s, and the previously described code handles the subscriptions, disposing them if they are already irrelevant due to the Activity
’s finished lifeficle
.