Wie zeige ich einen Dialog an, um zu bestätigen, dass der Benutzer eine Android-Aktivität beenden möchte?

Ich habe versucht, ein “Möchten Sie beenden?” Art des Dialogs, wenn der Benutzer versucht, eine Aktivität zu beenden.

Ich kann jedoch die entsprechenden API-Hooks nicht finden. Activity.onUserLeaveHint() sah zunächst vielversprechend aus, aber ich kann keine Möglichkeit finden, die Beendigung der Aktivität zu beenden.

   

In Android 2.0+ würde das so aussehen:

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

In früheren Versionen würde es so aussehen:

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

Habe @ user919216 code .. geändert und es mit WebView kompatibel gemacht

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

Ich würde lieber mit einem Doppelklick auf den Zurück-Button als mit einem Exit-Dialog beenden.

Bei dieser Lösung wird beim erstmaligen Zurückkehren ein Toast angezeigt, der darauf hinweist, dass ein weiterer Backpress die App schließt. In diesem Beispiel weniger als 4 Sekunden.

 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 von: http://www.androiduipatterns.com/2011/03/back-button-behavior.html

Wenn Sie nicht sicher sind, ob der Aufruf von “Zurück” die App beendet oder den Benutzer zu einer anderen Aktivität führt, können Sie die obigen Antworten in eine Prüfung, isTaskRoot (), einbinden. Dies kann passieren, wenn Ihre Hauptaktivität mehrmals zum Backstack hinzugefügt werden kann oder wenn Sie Ihren Backstack-Verlauf manipulieren.

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

Mit 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(); 

Sie müssen außerdem eine Level-Sprache einstellen, um Java 8 in Ihrem Gradle.build zu unterstützen:

 compileOptions { targetCompatibility 1.8 sourceCompatibility 1.8 } 

Entfernen Sie zuerst super.onBackPressed(); von der onbackPressed() Methode als und unter dem Code:

 @Override public void onBackPressed() { 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) { MyActivity.this.finish(); } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create(); alert.show(); } 

In China bestätigen die meisten App das Beenden durch “zweimal klicken”:

 boolean doubleBackToExitPressedOnce = false; @Override public void onBackPressed() { if (doubleBackToExitPressedOnce) { super.onBackPressed(); return; } this.doubleBackToExitPressedOnce = true; Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show(); new Handler().postDelayed(new Runnable() { @Override public void run() { doubleBackToExitPressedOnce=false; } }, 2000); } 

Ich mag einen @GLee-Ansatz und verwende ihn mit Fragmenten wie unten.

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

Dialog mit Fragment:

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

das funktioniert gut

 @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); } } 
 Just put this code in your first activity @Override public void onBackPressed() { if (drawerLayout.isDrawerOpen(GravityCompat.END)) { drawerLayout.closeDrawer(GravityCompat.END); } else { // if your using fragment then you can do this way int fragments = getSupportFragmentManager().getBackStackEntryCount(); if (fragments == 1) { 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) { finish(); } }) .setNegativeButton("No", null) .show(); } else { if (getFragmentManager().getBackStackEntryCount() > 1) { getFragmentManager().popBackStack(); } else { super.onBackPressed(); } } } } 

Eine andere Alternative wäre, eine Toast / Snackbar auf dem ersten AlertDialog zu zeigen und zu bitten, wieder zurück zu Exit zu drücken , was viel weniger aufdringlich ist, als einen AlertDialog zu zeigen, AlertDialog zu bestätigen, ob der Benutzer die App verlassen möchte.

Sie können die DoubleBackPress Android Library , um dies mit ein paar Zeilen Code zu erreichen. Beispiel GIF zeigt ähnliches Verhalten.

Fügen Sie die Abhängigkeit zunächst Ihrer Anwendung hinzu:

 dependencies { implementation 'com.github.kaushikthedeveloper:double-back-press:0.0.1' } 

Implementieren Sie als Nächstes in Ihrer Aktivität das erforderliche Verhalten.

 // set the Toast to be shown on FirstBackPress (ToastDisplay - builtin template) // can be replaced by custom action (new FirstBackPressAction{...}) FirstBackPressAction firstBackPressAction = new ToastDisplay().standard(this); // set the Action on DoubleBackPress DoubleBackPressAction doubleBackPressAction = new DoubleBackPressAction() { @Override public void actionCall() { // TODO : Exit the application finish(); System.exit(0); } }; // setup DoubleBackPress behaviour : close the current Activity DoubleBackPress doubleBackPress = new DoubleBackPress() .withDoublePressDuration(3000) // msec - wait for second back press .withFirstBackPressAction(firstBackPressAction) .withDoubleBackPressAction(doubleBackPressAction); 

Abschließend legen Sie dies als Verhalten beim Zurückdrücken fest.

 @Override public void onBackPressed() { doubleBackPress.onBackPressed(); }