Prevent back button from closing a dialog box

AndroidBack

Android Problem Overview


I am trying to prevent an AlertDialog box from closing when pressing the back button in Android. I have followed both of the popular methods in this thread, and with System.out.println I can see that in both cases the code executes. However, the back button still closes the dialog box.

What could I be doing wrong? Ultimately I'm trying to prevent the back button closing a dialog box - it is a disclaimer that is displayed the first time the app is run and I don't want the user to have any option but to press the "Accept" button in order for the app to continue.

Android Solutions


Solution 1 - Android

Simply use the setCancelable() feature:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);

This prevents the back button from closing the dialog, but leaves the "negative" button intact if you chose to use it.


While any user that does not want to accept your terms of service can push the home button, in light of Squonk's comment, here two more ways to prevent them from "backing out" of the user agreement. One is a simple "Refuse" button and the other overrides the back button in the dialog:

builder.setNegativeButton("Refuse", new OnClickListener() {
    	   @Override
    	   public void onClick(DialogInterface dialog, int which) {
    		   finish();
    	   }
       })
       .setOnKeyListener(new OnKeyListener() {
		   @Override
		   public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
			   if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP)
				   finish();
			   return false;
		   }
	   });

Solution 2 - Android

To prevent the back button closes a Dialog (without depending on Activity), just the following code:

alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
	@Override
	public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
		// Prevent dialog close on back press button
		return keyCode == KeyEvent.KEYCODE_BACK;
	}
});

Solution 3 - Android

When using DialogFragment you will need to call setCancelable() on the fragment, not the dialog:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    dialog = new ProgressDialog(getActivity());
    dialog.setIndeterminate(true);
    dialog.setMessage(...);
    setCancelable(false);

    return dialog;
}

Calling dialog.setCancelable() seem to have no effect. It seems that DialogFragment does not takes notice of the dialog's setting for cancelability.

Solution 4 - Android

Use setCancelable(false)

SampleDialog sampleDialog = SampleDialog.newInstance();
sampleDialog.setCancelable(false);
sampleDialog.show(getSupportFragmentManager(), SampleDialog.class.getSimpleName());

Solution 5 - Android

Only this worked for me:

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(title);
builder.setMessage(content);

/**
 * Make it when the Back button is pressed, the dialog isn't dismissed.
 */
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
            Utilities.makeToast(getContext(), "There is no way back!");
            return true; // Consumed
        }
        else {
            return false; // Not consumed
        }
    }
});

Dialog dialog = builder.create();

/**
 * Make it so touching on the background activity doesn't close the dialog
 */
dialog.setCanceledOnTouchOutside(false);

return dialog;

As you can see, I also added a dialog.setCanceledOnTouchOutside(false); line so tapping outside of the dialog doesn't result in it being closed either.

Solution 6 - Android

In JQuery Mobile a popup adds a hash to the url, the following code allows the back to dismiss the popup when open and return to the app when closed. You could use the same logic for a custom ui framework.

@Override
public void onBackPressed() {

    // check if modal is open #&ui-state=dialog

    if (webView.getVisibility() == View.VISIBLE && webView.getUrl().contains("#&ui-state=dialog")) {
        // don't pass back button action
        if (webView.canGoBack()) {
            webView.goBack();
        }
    } else {
        // pass back button action
        super.onBackPressed();
    }
}

Solution 7 - Android

Add setCancelable(false) to stop the back button from closing a dialog box.

For example :

AlertDialog.Builder builder = AlertDialog.Builder(this)
Dialog dialog = builder.create()
dialog.setCancelable(false)
dialog.setCanceledOnTouchOutside(false)

This will prevent the user from canceling the dialog when they press the back button or touch outside the dialog window

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCaptainProgView Question on Stackoverflow
Solution 1 - AndroidSamView Answer on Stackoverflow
Solution 2 - AndroidfalvojrView Answer on Stackoverflow
Solution 3 - AndroidOgnyanView Answer on Stackoverflow
Solution 4 - AndroidDavidView Answer on Stackoverflow
Solution 5 - Androidban-geoengineeringView Answer on Stackoverflow
Solution 6 - AndroidRicardo SaracinoView Answer on Stackoverflow
Solution 7 - AndroidIancu VladView Answer on Stackoverflow