shouldShowRequestPermissionRationale未按预期工作

时间:2017-09-04 15:25:08

标签: android android-permissions

我正在检查并获得API等级23及以上的用户的许可。所以这对我来说是个令人困惑的事情,android.com说:

  

如果应用先前已请求此权限且用户拒绝了该请求,那么shouldShowRequestPermissionRationale()方法将返回true。   如果用户过去拒绝了权限请求并在权限请求系统对话框中选择了“不再询问”选项,则此方法返回false

在另一方面,它提供以下代码用于检查权限和请求权限(如果其必要的

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.READ_CONTACTS)
    != PackageManager.PERMISSION_GRANTED) {

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
        Manifest.permission.READ_CONTACTS)) {

    // Show an explanation to the user *asynchronously* -- don't block
    // this thread waiting for the user's response! After the user
    // sees the explanation, try again to request the permission.

} else {

    // No explanation needed, we can request the permission.

    ActivityCompat.requestPermissions(thisActivity,
            new String[]{Manifest.permission.READ_CONTACTS},
            MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
    // app-defined int constant. The callback method gets the
    // result of the request.
    }
}
如果用户不允许权限并检查不再询问,则上述示例中的

else范围会运行,对吗?因此,在第一次运行时,用户永远不会被要求获得许可。我测试了那段代码,结果就是我的预期。 那么,如果用户先前拒绝了我的请求,如果用户拒绝我的请求并检查不再询问,我怎么能请求第一次运行的权限并执行某些操作?

6 个答案:

答案 0 :(得分:0)

首先检查是否授予了权限然后执行您需要的操作 否则,如果许可被拒绝,那么检查天气你应该通过shouldShowRequestPermissionRationale请求你需要的权限。
如果shouldShowRequestPermissionRationale返回false,那么您只需向用户显示一条消息,告诉他们手动启用权限。
其他如果shouldShowRequestPermissionRationale返回true则请求权限并获取onRequestPermissionsResult中授予权限的结果

更新,这只是一个显示步骤的简单代码:

if (checkSelfPermission == granted){
 // do what you want 
 } else if (shouldShowRequestPermissionRationale == true) {
        // you can request the permission you want from the user, then check whether permission granted or not inside onRequestPermissionsResult method
 } else { 
        // here you know the permission is not granted , and also the user check on "Dont ask Again!" checkbox, so all you can to do is just tell the user to enable the permission manually from app permissions through Toast message or any thing else
        }

答案 1 :(得分:0)

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

      //initilize your views


    if(iscontactsAllowed){

    // do your code here

    } else {

     requestcontactsPermission();

    }

}
private void requestcontactsPermission() {

        if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_CONTACTS)) {
            //If the user has denied the permission previously your code will come to this block
            //Here you can explain why you need this permission
            //Explain here why you need this permission
            Log.d("scancode", "denied permission before");
        }

        Log.d("perm", "fourth");
        //And finally ask for the permission
        ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_CONTACTS}, READ_CONTACTS_CODE /*can be any interge */);

    }

private boolean iscontactsAllowed() {
            //Getting the permission status
            int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_CONTACTS);

            //If permission is granted returning true
            if (result == PackageManager.PERMISSION_GRANTED)

                return true;

            //If permission is not granted returning false
            return false;
        }


@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        //Checking the request code of our request

        if(requestCode == READ_CONTACTS_CODE){

if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// you have the permission call yur method here

} else {

// permission denied show user why you need it or ask again by calling reuestpermission if you need the permission
}

}

答案 2 :(得分:0)

@ArtinArtin我已经扩展了@salmanyahya更新的简单代码,并提供了我的逻辑与警报对话框和一个Snackbar(不是Snackbar的大粉丝)任何方式看看这是否有帮助

       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            //.... write file into storage ...
            System.out.println("SDK > BuildVersion TRUE");
        } else {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 666);  // Comment 26
            System.out.println("go to requestPermissions");
        }
    }
    onLoad();
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {

        case 666: // Allowed was selected so Permission granted
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                Snackbar s = Snackbar.make(findViewById(android.R.id.content),"Permission Granted",Snackbar.LENGTH_LONG);
                View snackbarView = s.getView();
                TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
                textView.setTextColor(Color.RED);
                textView.setTextSize(18);
                textView.setMaxLines(6);
                s.show();

                // do your work here

            } else if (Build.VERSION.SDK_INT >= 23 && !shouldShowRequestPermissionRationale(permissions[0])) {
                // User selected the Never Ask Again Option Change settings in app settings manually
                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
                alertDialogBuilder.setTitle("Change Permissions in Settings");
                alertDialogBuilder
                        .setMessage("" +
                                "\nClick SETTINGS to Manually Set\n"+"Permissions to use Database Storage")
                        .setCancelable(false)
                        .setPositiveButton("SETTINGS", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                Uri uri = Uri.fromParts("package", getPackageName(), null);
                                intent.setData(uri);
                                startActivityForResult(intent, 1000);     // Comment 3.
                            }
                        });

                AlertDialog alertDialog = alertDialogBuilder.create();
                alertDialog.show();

            } else {
                    // User selected Deny Dialog to EXIT App ==> OR <== RETRY to have a second chance to Allow Permissions
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {

                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
                    alertDialogBuilder.setTitle("Second Chance");
                    alertDialogBuilder
                            .setMessage("Click RETRY to Set Permissions to Allow\n\n"+"Click EXIT to the Close App")
                            .setCancelable(false)
                            .setPositiveButton("RETRY", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int id) {
                                    //ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, Integer.parseInt(WRITE_EXTERNAL_STORAGE));
                                    Intent i = new Intent(MainActivity.this,MainActivity.class);
                                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(i);
                                    }
                            })
                            .setNegativeButton("EXIT", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int id) {
                                    finish();
                                    dialog.cancel();
                                }
                            });
                    AlertDialog alertDialog = alertDialogBuilder.create();
                    alertDialog.show();
                }
            }
            break;
    }};

答案 3 :(得分:0)

此代码有助于处理Android中的运行时权限管理

select * 
from table 
ORDER BY 
cast(substring(doc_unique_id, charindex('-', doc_unique_id)+1, len(doc_unique_id)) as int)

答案 4 :(得分:0)

您可以执行以下操作。

  1. 每次仅通过检查是否已授予许可来询问许可。请勿使用这种方法处理“不再询问” 。 (如果用户选中“不再询问” ,则操作系统将自动处理并且不会再次请求许可,并且会回回拒绝的许可)
  2. 在回调方法onRequestPermissionsResult()中处理 ActivityCompat.shouldShowRequestPermissionRationale()

这是我每次都要求许可的代码

public void checkAndAskCameraPermission() {
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(context,
                    new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_ID);
        }
    }

这就是我处理回叫的方式

@Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case CAMERA_PERMISSION_REQUEST_ID: {
                if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {

                  // Do something if permission is not granted and the user has also checked the **"Don't ask again"**
                } else if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
                    // Do something if permission not granted
                }
            }
        }
    }

答案 5 :(得分:0)

我发现的是,仅当用户拒绝许可(至少一次)并且未选择“不再询问”时,shouldShowRequestPermissionRationale才返回true。意思是,它也不会在第一次请求权限时显示。