NoNews / NoPermission

Android library for permissions request (updated 27.11.2017)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bug when close and reopen

pellyadolfo opened this issue · comments

Thanks for this class. The beauty of simplicity.

There seems to be a bug when showing the permission request to the user on the splash screen. If the user cleans his dialog and opens again the app, this secod time, the permissionHelper.check() method automatically executes 'success' and assumes to be granted, without showing the dialog again and without actually having the permission granted.

In this way, clearing the screen and reopening the app in the same point (i.e. moving the app to background and back to foreground) we can navigate the app skipping the dialogs until the final security crash.

The problem is that when I reopen the app (onResume), Android calls onRequestPermissionsResult with empty arrays for permissions and grantResults.

"When the user responds to your app's permission request, the system invokes your app's onRequestPermissionsResult() method, passing it the user response. Your app has to override that method to find out whether the permission was granted". https://developer.android.com/training/permissions/requesting.html

My work around is not executing your code in this case (i.e. when the arrays are empty). If I do, permissionHelper runs onSuccess method.

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if(grantResults.length == 0)
        return;
    permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

Hi @pellyadolfo , thanks for this issue.
What you mean by "user clean the dialog"?

Can you show the full code at your SplashActivity?

Hi @NoNews,

I mean, scenario: the app is showing the permission request dialog to the user and, in this moment, the user clicks the button in the middle (https://i.stack.imgur.com/RPdkA.png) to move the app to background. If the user moves the app back to foreground (by clicking the third button), the dialog does not show again (as would be expected) and the onResume executes method onRequestPermissionsResult passing an empty array. Current NoPermission code moves the flow to the onSuccess Runnable and allows the user to pass without having accepted the permission.

Later I paste some code at home.

@pellyadolfo Thank you, I'll debug this moment today

@pellyadolfo I could to reproduce crash (but not security crash), will fix it on this weekend. (And release new version)

I still need your code. I follow your scenario, method onSuccess is not called on my device

This is a kind of parent activity

public abstract class APermissionActivity extends AppCompatActivity {
    private static PermissionHelper permissionHelper = null;

    protected void initializePermission() {
        if (permissionHelper == null)
            permissionHelper = new PermissionHelper(this); //don't use getActivity in fragment!
    }

    protected void verifyPermission(String permission, Runnable onSuccess, Runnable onDenied, Runnable onNeverAskAgain) {
        permissionHelper.check(permission)
                //.withDialogBeforeRun(R.string.dialog_before_run_title, R.string.dialog_before_run_message, R.string.dialog_positive_button)
                .setDialogPositiveButtonColor(android.R.color.holo_orange_dark)
                .onSuccess(onSuccess)
                .onDenied(onDenied)
                .onNeverAskAgain(onNeverAskAgain)
                .run();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if(grantResults.length == 0)
            return;

        permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

and this is how I use it in a subclass:

    verifyPermission(Manifest.permission.ACCESS_FINE_LOCATION,
            new Runnable() {
                @Override
                public void run() {
                    log("onSuccess permission - " + Manifest.permission.ACCESS_FINE_LOCATION);
                }
            }, new Runnable() {
                @Override
                public void run() {
                    log("Denied permission - " + Manifest.permission.ACCESS_FINE_LOCATION);
                }
            }, new Runnable() {
                @Override
                public void run() {
                    log(" NeverAskAgain permission - " + Manifest.permission.ACCESS_FINE_LOCATION);
                }
            });

on resuming the activity, android calls onRequestPermissionsResult with empty String[] and I find it runs onSuccess exactly here https://github.com/NoNews/NoPermission/blob/master/library/src/main/java/ru/alexbykov/nopermission/PermissionHelper.java#L353

Is like Android understands that the user has responded: "When the user responds to your app's permission request, the system invokes your app's onRequestPermissionsResult() method, passing it the user response. Your app has to override that method to find out whether the permission was granted".

This is why a try to fix it by blocking this weird event with

    if(grantResults.length == 0)
        return;

I am on API level 24.

@pellyadolfo
I trying to reproduce this behavior, I do on the case:

  1. Show the system permission dialog (for example, location permission)
  2. Press the "Home" button
  3. Return in application (in foreground)

Actual result:

  • System permission dialog currently showing
  • Method onRequestPermissionResult not executed with empty grandetResults
    Android not execute it, if the user has not made a choice (Allow or Deny)

Devices:

  • Pixel API 24,
  • Nexus 5x, API 25

@pellyadolfo Can you try reproduce it with sample application?