fondesa / kpermissions

A Kotlin library which helps to request runtime permissions in Android.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why is fragment onResume called after permission request was sent?

thats-bot opened this issue · comments

 private fun checkCameraPermission() {
        // Build the request with the permissions you would like to request and send it.
        permissionsBuilder(Manifest.permission.CAMERA).build().send { result ->
            // Handle the result, for example check if all the requested permissions are granted.
            if (result.first().isGranted()) {
                // All the permissions are granted.
            } else {
                showPermissionError()
            }
        }
    }

After checking permission inside androidx.fragment in onResume I get an infinity loop.
onResume is called every time I request permission. And even if permission is granted and there is no popup dialog showing.
Is this an expected behaviour? Or how to avoid it?

This is an expected behavior for now because when the Android permissions dialog appears, the fragments at the same level of that dialog are going to be paused.

You have 3 options to avoid it:

  1. refactor your code without using onResume() to handle the permissions.
  2. hold an internal state in your Fragment to avoid to run in an infinite loop.

e.g.

private var hasRequestedPermissions = false

override fun onResume() {
    super.onResume()
    if(!hasRequestedPermissions) {
        hasRequestedPermissions = true
        // Build the request with the permissions you would like to request and send it.
        permissionsBuilder(Manifest.permission.CAMERA).build().send { result ->
            // Handle the result, for example check if all the requested permissions are granted.
            if (result.first().isGranted()) {
                // All the permissions are granted.
            } else {
                showPermissionError()
            }
            hasRequestedPermissions = false
        }
    }
}
  1. Write a custom RuntimePermissionHandlerProvider and set it on the PermissionBuilder. This is cleaner but it requires more time to implement it and I don't think it's worth if you have only this use-case.

Said that, I'm explaining why the library currently behaves like this.
The library uses the Activity reference for both Activity and Fragment permissions to avoid runtime permissions requests clashes. It means that if you have the Activity A and the Fragment B contained in the Activity A, if you send in the same moment a runtime permissions request, the same permissions dialog is used.
Using the Fragment instance to request the permissions would cause the loss of this behavior.
Giving weights to both things, I think that behavior is more important than supporting onResume natively since your problem can be fixed with one of those 3 solutions above while fixing the other problem would be much more tricker.

By the way, I'll think more to a solution which supports both of them (obviously, if you have one already in mind or you wish to work on it, feel free to contribute to the repo). If there's a way to support both behaviors it would be great to integrate it.

I'm leaving this question open until I'll be sure there aren't solutions to support both behaviors.

OFF-TOPIC
Since you want to check all your permissions are granted, you can use result.allGranted() instead of result.first().isGranted() btw.

My bad, apparently this is the intended Android behavior anyway. You can't ask permissions in onResume() without any control-flag.