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:
- Show the system permission dialog (for example, location permission)
- Press the "Home" button
- Return in application (in foreground)
Actual result:
- System permission dialog currently showing
- Method
onRequestPermissionResult
not executed with emptygrandetResults
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?