Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


¿Cómo mostrar un diálogo para confirmar que el usuario desea salir de una actividad de Android?

He estado tratando de mostrar un "¿Quieres salir?" Tipo de diálogo cuando el usuario intenta salir de una actividad.

Sin embargo, no puedo encontrar los ganchos API apropiados. Activity.onUserLeaveHint() inicialmente parecía prometedora, pero no puedo encontrar una manera de detener la actividad de terminar.

8 Solutions collect form web for “¿Cómo mostrar un diálogo para confirmar que el usuario desea salir de una actividad de Android?”

En Android 2.0+ esto se vería así:

 @Override public void onBackPressed() { new AlertDialog.Builder(this) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle("Closing Activity") .setMessage("Are you sure you want to close this activity?") .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }) .setNegativeButton("No", null) .show(); } 

En las versiones anteriores sería como:

 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { //Handle the back button if(keyCode == KeyEvent.KEYCODE_BACK) { //Ask the user if they want to quit new AlertDialog.Builder(this) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle(R.string.quit) .setMessage(R.string.really_quit) .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //Stop the activity YourClass.this.finish(); } }) .setNegativeButton(R.string.no, null) .show(); return true; } else { return super.onKeyDown(keyCode, event); } } 
 @Override public void onBackPressed() { new AlertDialog.Builder(this) .setMessage("Are you sure you want to exit?") .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { ExampleActivity.this.finish(); } }) .setNegativeButton("No", null) .show(); } 

Han modificado el código @ user919216 .. y lo han hecho compatible con WebView

 @Override public void onBackPressed() { if (webview.canGoBack()) { webview.goBack(); } else { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Are you sure you want to exit?") .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { finish(); } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create(); alert.show(); } } 

Preferiría salir con doble pulsación en el botón de retroceso que con un diálogo de salida.

En esta solución, muestra un brindis cuando vuelve por primera vez, advirtiendo que otra prensa posterior cerrará la aplicación. En este ejemplo menos de 4 segundos.

 private Toast toast; private long lastBackPressTime = 0; @Override public void onBackPressed() { if (this.lastBackPressTime < System.currentTimeMillis() - 4000) { toast = Toast.makeText(this, "Press back again to close this app", 4000); toast.show(); this.lastBackPressTime = System.currentTimeMillis(); } else { if (toast != null) { toast.cancel(); } super.onBackPressed(); } } 

Token de: http://www.androiduipatterns.com/2011/03/back-button-behavior.html

Si no está seguro si la llamada a "volver" saldrá de la aplicación, o llevará al usuario a otra actividad, puede envolver las respuestas anteriores en un cheque, isTaskRoot (). Esto puede suceder si su actividad principal se puede agregar a la pila trasera varias veces, o si está manipulando el historial de la pila trasera.

 if(isTaskRoot()) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Are you sure you want to exit?") .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { YourActivity.super.onBackPressed; } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create(); alert.show(); } else { super.onBackPressed(); } 

Uso de Lambda:

  new AlertDialog.Builder(this).setMessage(getString(R.string.exit_msg)) .setTitle(getString(R.string.info)) .setPositiveButton(getString(R.string.yes), (arg0, arg1) -> { moveTaskToBack(true); finish(); }) .setNegativeButton(getString(R.string.no), (arg0, arg1) -> { }) .show(); 

También necesita establecer un lenguaje de nivel para admitir java 8 en su gradle.build:

 compileOptions { targetCompatibility 1.8 sourceCompatibility 1.8 } 

Me gusta un enfoque @Gee y usarlo con fragmentos como a continuación.

 @Override public void onBackPressed() { if(isTaskRoot()) { new ExitDialogFragment().show(getSupportFragmentManager(), null); } else { super.onBackPressed(); } } 

Diálogo que utiliza Fragmento:

 public class ExitDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new AlertDialog.Builder(getActivity()) .setTitle(R.string.exit_question) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { getActivity().finish(); } }) .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { getDialog().cancel(); } }) .create(); } } 

Esto funciona bien

 @Override public void onBackPressed() { if (mExitOnBackPress) finish(); else { Toast.makeText(this, R.string.msg_confirm_exit, Toast.LENGTH_SHORT).show(); mExitOnBackPress = true; new android.os.Handler().postDelayed(new Runnable() { @Override public void run() { mExitOnBackPress = false; } }, 2000); } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.