Проблема с разрешением Android M с диалоговым окном "Не спрашивайте снова"

Это более простой способ предоставить разрешение с помощью ограниченного доступа к каталогам, но Dialog покажет флажок "Не спрашивать снова". Если пользователь выбирает Не спрашивать снова и отказывает в запросе, все будущие запросы для данного каталога из вашего приложения будут автоматически отклоняться, и пользовательский интерфейс запроса не будет представлен пользователю. если пользователь сожалеет или ударит по этому флажку по ошибке, как можно защитить приложение? приложение не может получить разрешение.

Как мы можем справиться с этим?

Ответ 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();
    }

Ответ 2

  есть ли способ изменить этот флаг?

Разработчик не может изменить этот флаг. В противном случае было бы бессмысленно иметь этот флажок, так как разработчики просто проигнорировали бы его, изменив флаг.

Тем не менее, ваш вопрос указывает на довольно существенный недостаток доступа к каталогу в заданной области: пользователь имеет ограниченные возможности для изменения этого флага. Кажется, в настройках нет места для конкретного изменения этого состояния, так как пользователь может вручную предоставить отклоненное разрешение во время выполнения.

На Nexus 5X с предварительным просмотром 7.1 "Очистить данные" сбросит этот флаг, хотя это имеет более широкие эффекты. На Google Pixel под управлением 7.1 и на Nexus 5X под управлением Android 7.0 этот флаг не будет сброшен ничем, даже полная деинсталляция приложения.

Я подал отчет об ошибке по этому поводу. Я скептически отношусь к тому, что в краткосрочной перспективе ситуация значительно улучшится &— в лучшем случае они могут это исправить, так что "Очистка данных" работает надежно.

Ответ 3

Откройте настройки разрешений приложения.

Вы не можете отобразить другое диалоговое окно с разрешениями, если пользователь установил флажок "Больше не спрашивать".

Тем не менее, вы можете помочь пользователю и открыть настройки приложения, где пользователь может вручную включить необходимые разрешения.

Для этого вам нужно запустить намерение, похожее на это:

public void openAppSettings() {

    Uri packageUri = Uri.fromParts( "package", getApplicationContext().getPackageName(), null );

    Intent applicationDetailsSettingsIntent = new Intent();

    applicationDetailsSettingsIntent.setAction( Settings.ACTION_APPLICATION_DETAILS_SETTINGS );
    applicationDetailsSettingsIntent.setData( packageUri );
    applicationDetailsSettingsIntent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );

    getApplicationContext().startActivity( applicationDetailsSettingsIntent );

}

Теперь, чтобы узнать, когда пользователь снял флажок "Больше не спрашивать", это другой вопрос, который можно сделать с помощью этого ответа Qaru.

Ответ 4

Я думаю, что вам нужно использовать метод shouldShowRequestPermissionRationale (String), он вернет false, если пользователь отказал в разрешении и проверил "Не спрашивать снова".

Что вы должны сделать, это показать предупреждение, объясняющее пользователя, почему вам нужно разрешение или реализовать резервную копию, например, отключить некоторые функции.

Надеюсь быть полезным.

Ответ 5

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;
    }
}

Ответ 6

Я создал метод для захвата всех действий пользователя с использованием сцепленного if... else if... else, и он работал хорошо для меня.
Во-первых, чтобы определить, было ли как разрешение, так и отказ " Этот запрос был также отмечен галочкой, я объединил проверку статуса разрешения и mustShowRequestPermissionRationale (Manifest.permission.SEND_SMS).
Затем, чтобы определить, было ли отказано только в разрешении without без "галочки" DL5, "Не спрашивать снова", я использовал проверку статуса разрешения. Ниже фрагмент:

@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);

                        }
        }