4

I think there is a bug shouldShowRequestPermissionRationale

Code is...

@Override
protected void onResume() {
    super.onResume();
    if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_DENIED &&
            ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) {
        if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION) ||
                ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
            new AlertDialog.Builder(this)....show();
    } else {
        // do something...
}

Installed the app first, We do not allow the permission. So when onResume is called, AlertDialog should appears. But it's not appear...

If we go into the setting of the app, and allow the permission. So We play the app code(// do something). Again, we go into the setting of the app, Deny the permission. And we restart the app, AlertDialog appears.

Why the app runs like this ?

fasdgoc
  • 69
  • 1
  • 7
  • `shouldShowRequestPermissionRationale()` will only return true if you **HAVE NOT** checked the checkbox which says don't ask me again – Aman Grover Sep 28 '16 at 05:31
  • I didnt check the checkbox. – fasdgoc Sep 28 '16 at 05:33
  • @fasdgoc See [this](http://stackoverflow.com/a/34612503/3117966) for more info – Nisarg Sep 28 '16 at 05:34
  • Have you tried to debug and check whether it executes the sub if condition or not? I think its not executing the second condition. – GrIsHu Sep 28 '16 at 05:37
  • @AmanGrover First, I installed the app. and run the app. AlertDialog does not appears.(First, Permission is not granted) – fasdgoc Sep 28 '16 at 05:37
  • @GrIsHu Right. In a case that we installed the app, Second condition returns false.. but i didn't check the check box which says don't ask me again. Of course, permission dialog didn't appear. – fasdgoc Sep 28 '16 at 05:49
  • @fasdgoc You got to allow the permission then and only than your second condition is going to execute. – GrIsHu Sep 28 '16 at 05:51
  • @GrIsHu I tried do that, but If we code `requestPermissions` in `checkSelfPermission`(direct child of onResume) directly, onResume is called infinitely... because, we request the permission(permission dialog appears -> activity state is onPause -> user do not allow the permission -> onResume -> ..... infinite call!! – fasdgoc Sep 28 '16 at 06:12
  • But If i removed the code `shouldShowRequestPermissionRationale`, All is work well. Can i don't use the `shouldShowRequestPermissionRationale` ? – fasdgoc Sep 28 '16 at 06:20
  • As a result, We first installed the app(in this case we didn't check the checkbox says don't ask me again of course, nonetheless `checkSelfPermissions` returns false) – fasdgoc Sep 28 '16 at 06:22
  • please post your code in onCreate() ? – Ashish Shukla Sep 28 '16 at 06:37
  • @AshishShukla onCreate didn't anything. – fasdgoc Sep 28 '16 at 06:40
  • are you using this method ActivityCompat.requestPermissions()? – Ashish Shukla Sep 28 '16 at 06:41
  • @AshishShukla Yes. In the OK button of AlertDialog. – fasdgoc Sep 28 '16 at 06:43
  • @fasdgoc Your question is not clear please explain properly in which case you want to show dialog? Its confusing. Explain properly. – GrIsHu Sep 28 '16 at 06:45
  • @GrIsHu First, I want request permission onResume directly. but if user deny the permission and do nothing, onPause is called(when permission request dialog is opened..) and onResume is called(when that permission request dialog is closed) and request dialog is opened again and again... – fasdgoc Sep 28 '16 at 06:50
  • So I moved the request function from child of `checkSelfPermission` to AlertDialog's positiveButton – fasdgoc Sep 28 '16 at 06:51
  • fasdgoc I think you didn't understood my answer, the problem with your code was that you were requesting the permission at wrong place and I focused on that.The OP is just explaining your code not providing the exact answer. – Ashish Shukla Sep 28 '16 at 08:47
  • @AshishShukla I understood what you mean. Buti installed the app, Initial state of the app's permission is denial. But In a case that `requestPermissions` is in onResume directly, Request Dialog appears infinitely. Cuz, Request dialog appears and activity state is `pause`. If user deny the permission this time, Request Dialog disappers and activity state is `resume`. But now permission is denyed So request dialog appears again and again.. – fasdgoc Sep 28 '16 at 08:58
  • How did Swamy's answer helped you ? – Ashish Shukla Sep 28 '16 at 09:09
  • That's not important here. Sorry about that. BTW I think Showing AlertDialog can used. Because it doesnt call the activitys onPause – fasdgoc Sep 28 '16 at 09:15
  • I didnt told you that you cannot call AlertDialog , I just told you don't call requestPermission on Button click bcoz I suggested to call requestPermission some where else. – Ashish Shukla Sep 28 '16 at 09:21
  • But i want to place requestPermissions in onResume. What i want is that If user change acticity(onPause-> onResume cases..), request dialog appears(user didn't allow the permission) – fasdgoc Sep 28 '16 at 09:24
  • But Problem is request dialog calls the onPause onResume sequence... – fasdgoc Sep 28 '16 at 09:25
  • @AshishShukla I think `onRestart` and `onCreate` Pair can be used..... i will do that shortly.. by the way Thank you.. – fasdgoc Sep 28 '16 at 09:32

3 Answers3

5

From Developers Docs :

shouldShowRequestPermissionRationale()

This method returns true if the app has requested this permission previously and the user denied the request.

Note: If the user turned down the permission request in the past and chose the Don't ask again option in the permission request system dialog, this method returns false.

The issue is that you haven't requested the permission before using

 ActivityCompat.requestPermissions();

Hence its not showing the dialog.

When you manually give permission or deny permission from Settings its assumed that you denied the permission and thats why it showing the Alert Dialog.

Community
  • 1
  • 1
Ashish Shukla
  • 1,027
  • 16
  • 36
  • just follow the way in below answer and on click of button dont ask again for permission – Ashish Shukla Sep 28 '16 at 07:05
  • Could you provide a link to that Developers Doc? They don't provide that much detail at [this link](https://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#shouldShowRequestPermissionRationale(android.app.Activity,%20java.lang.String)). – jk7 Feb 23 '17 at 20:20
  • follow this link https://developer.android.com/training/permissions/requesting.html – Ashish Shukla Feb 24 '17 at 06:58
1

Worked with Gmail API and found another option in its sample code regarding Android permissions. You may want to use EasyPermissions which was provided by Google itself, to, as said, "Simplify Android M system permissions".

Wei WANG
  • 1,748
  • 19
  • 23
0

Check this implementation. is working pretty good for me. basically you check the permissions in the checkPermissions() method passing a list of permissions. You check the result of the permission request on onRequestPermissionsResult(). The implementation lets u address both case when user selects "never ask again" or not. In this implementation, in case se selects "never ask again", the dialog has an option to take him to the App Settings Activity.

All this code is inside my fragment. I was thinking that would be better to create a specialised class to do this, like a PermissionManager, but i'm not sure about it.

/**
     * responsible for checking if permissions are granted. In case permissions are not granted, the user will be requested and the method returns false. In case we have all permissions, the method return true.
     * The response of the request for the permissions is going to be handled in the onRequestPermissionsResult() method
     * @param permissions list of permissions to be checked if are granted onRequestPermissionsResult().
     * @param requestCode request code to identify this request in
     * @return true case we already have all permissions. false in case we had to prompt the user for it.
     */
    private boolean checkPermissions(List<String> permissions, int requestCode) {
        List<String> permissionsNotGranted = new ArrayList<>();
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(getActivity(), permission) != PackageManager.PERMISSION_GRANTED)
                permissionsNotGranted.add(permission);
        }

        //If there is any permission we don't have (it's going to be in permissionsNotGranted List) , we need to request.
        if (!permissionsNotGranted.isEmpty()) {
            requestPermissions(permissionsNotGranted.toArray(new String[permissionsNotGranted.size()]), requestCode);
            return false;
        }
        return true;
    }

    /**
     * called after permissions are requested to the user. This is called always, either
     * has granted or not the permissions.
     * @param requestCode  int code used to identify the request made. Was passed as parameter in the
     *                     requestPermissions() call.
     * @param permissions  Array containing the permissions asked to the user.
     * @param grantResults Array containing the results of the permissions requested to the user.
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case YOUR_REQUEST_CODE: {
                boolean anyPermissionDenied = false;
                boolean neverAskAgainSelected = false;
                // Check if any permission asked has been denied
                for (int i = 0; i < grantResults.length; i++) {
                    if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                        anyPermissionDenied = true;
                        //check if user select "never ask again" when denying any permission
                        if (!shouldShowRequestPermissionRationale(permissions[i])) {
                            neverAskAgainSelected = true;
                        }
                    }
                }
                if (!anyPermissionDenied) {
                    // All Permissions asked were granted! Yey!
                    // DO YOUR STUFF
                } else {
                    // the user has just denied one or all of the permissions
                    // use this message to explain why he needs to grant these permissions in order to proceed
                    String message = "";
                    DialogInterface.OnClickListener listener = null;
                    if (neverAskAgainSelected) {
                        //This message is displayed after the user has checked never ask again checkbox.
                        message = getString(R.string.permission_denied_never_ask_again_dialog_message);
                        listener = new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                //this will be executed if User clicks OK button. This is gonna take the user to the App Settings
                                startAppSettingsConfigActivity();
                            }
                        };
                    } else {
                        //This message is displayed while the user hasn't checked never ask again checkbox.
                        message = getString(R.string.permission_denied_dialog_message);
                    }
                    new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme)
                            .setMessage(message)
                            .setPositiveButton(getString(R.string.label_Ok), listener)
                            .setNegativeButton(getString(R.string.label_cancel), null)
                            .create()
                            .show();
                }
            }
            break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    /**
     * start the App Settings Activity so that the user can change
     * settings related to the application such as permissions.
     */
    private void startAppSettingsConfigActivity() {
        final Intent i = new Intent();
        i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        i.addCategory(Intent.CATEGORY_DEFAULT);
        i.setData(Uri.parse("package:" + getActivity().getPackageName()));
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        getActivity().startActivity(i);
    }
Thiago Saraiva
  • 181
  • 1
  • 10