Проблема с разрешением 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);
}
}