对话框的Android M权限问题“不要再问了”

时间:2016-11-17 12:11:33

标签: android android-permissions

这是一种通过Scoped Directory Access授予权限的更简单方法,但Dialog将显示一个名为“Do not ask again”的复选框。如果用户选择“不再询问”并拒绝该请求,则将自动拒绝您应用中对给定目录的所有未来请求,并且不会向用户显示请求UI。   如果用户后悔或错误地点击了该复选框,应用程序如何解决?应用无法获得权限对话框。

我们如何处理这个?

5 个答案:

答案 0 :(得分:6)

  

是否可以改变那面旗帜?

开发人员无法更改该标志。否则,拥有该复选框是没有意义的,因为开发人员会通过更改标志来忽略它。

但是,您的问题指出了作用域目录访问中存在相当大的缺陷:用户更改该标志的能力有限。 “设置”中似乎没有专门更改此状态的位置,即用户可以手动授予被拒绝的运行时权限的方式。

在运行7.1预览的Nexus 5X上,“清除数据”将重置此标志,但效果更广。在运行7.1的Google Pixel和运行Android 7.0的Nexus 5X上, nothing 将重置此标记,甚至是应用程序的完全卸载。

我已就此提出a bug report。我怀疑这种情况会在短期内得到很大改善 - 充其量,他们可能会解决这个问题,以便“清晰数据”能够可靠地运作。

答案 1 :(得分:2)

我认为您需要做的是使用方法shouldShowRequestPermissionRationale(String)如果用户拒绝了该权限并返回“不再询问”,则会返回false。

您应该做的是显示一条警告,向用户解释您需要获得权限的原因或实施回退,例如禁用某些功能。

希望有所帮助。

答案 2 :(得分:1)

我们应该使用shouldShowRequestPermissionRationale。请仔细阅读:

private void insertDummyContactWrapper() {
        int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);
        if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
                if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {
                    showMessageOKCancel("You need to allow access to Contacts",
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
                                            REQUEST_CODE_ASK_PERMISSIONS);
                                }
                            });
                    return;
                }
            requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
                    REQUEST_CODE_ASK_PERMISSIONS);
            return;
        }
        insertDummyContact();
    }

答案 3 :(得分:1)

public class AccessDenied implements View.OnClickListener{

    public Dialog dialog;
    private LinearLayout contentLayout;
    private Activity context;
    private EditText password;
    private String passwordStr;
    private Runnable doOnAccessPermitted;
    private int wrongColor = Color.RED, defColor = Color.parseColor("#80000000");


    public AccessDenied(Activity con, String pwd) {
        passwordStr = pwd;
        context = con;
        dialog = new Dialog(context, R.style.AnimatedDialog);
        setCancelable(false);
        //init the dialog with content view/animations etc.
        dialog.setContentView(R.layout.access_denied_layout);
        contentLayout = dialog.findViewById(R.id.layoutIconDialogLinearLayout);
        password = dialog.findViewById(R.id.accessdeniedlayoutpassword);
        Button ok = dialog.findViewById(R.id.accessdeniedlayoutok);
        ok.setOnClickListener(this);
        //now the dialog is ready
    }

    public void setActionOnAccess(Runnable doOnAccess) {
        doOnAccessPermitted = doOnAccess;
    }

    public void setCancelable(boolean set) {
        dialog.setCancelable(set);
    }

    public void show() {
        dialog.show();
    }

    public void cancel() {
        dialog.cancel();
    }

    public void setPassword(String pwrd) {
        passwordStr = pwrd;
    }

    public void tryPassword(String tryp) {
        if(passwordStr.equals(tryp)){
            cancel();
            if(doOnAccessPermitted != null)
                doOnAccessPermitted.run();
        }
    }

    @Override
    public void onClick(View view) {
        if(passwordStr.equals(password.getText().toString())) {
            cancel();
            if(doOnAccessPermitted != null)
                doOnAccessPermitted.run();
        }else{
            password.getText().clear();
            Animation anim = AnimationUtils.loadAnimation(context, R.anim.edittext_shake);
            anim.setDuration(200);
            anim.setRepeatCount(5);
            decView().startAnimation(anim);
            decView().setBackgroundColor(wrongColor);
            new android.os.Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    decView().setBackgroundColor(defColor);
                }
            }, 1000);
        }
    }

    private View decView() {
        return password;
    }
}

答案 4 :(得分:0)

我创建了一种方法,该方法使用级联的 if ... else if ... else 捕获所有用户操作,对我来说效果很好。
首先,确定是否两个权限均被拒绝,“不要再问”也被“选中” ,我将权限状态检查和shouldShowRequestPermissionRationale(Manifest.permission.SEND_SMS)结合在一起。
然后,为了确定是否仅拒绝拒绝了该许可,“点击”“不再询问”,我使用了许可状态检查。摘录下方:

@RequiresApi(api = Build.VERSION_CODES.M) //this is added for API lower than 23

public void myPermissionRationale(){
        //This checks both permission status and the Don't ask again check box
        if (ContextCompat.checkSelfPermission(this,Manifest.permission.SEND_SMS )
                == PackageManager.PERMISSION_DENIED && !shouldShowRequestPermissionRationale(Manifest.permission.SEND_SMS)) {
            //open app permission settings here for instance 

        }
           //only checks permission status then shows permission request pop up again
           else if (ContextCompat.checkSelfPermission(this,Manifest.permission.SEND_SMS )
                    == PackageManager.PERMISSION_DENIED){
                            // Request the permission
                            ActivityCompat.requestPermissions(this,
                                    new String[]{Manifest.permission.SEND_SMS},
                                    10);

                        }
        }