Klicken Sie zweimal auf die Schaltfläche "Zurück", um eine Aktivität zu beenden

Ich habe dieses Muster in einer Menge von Android-Apps und Spiele vor kurzem bemerkt: Wenn du auf die Schaltfläche "Zurück" klickst, um die Anwendung zu "beenden", kommt ein Toast mit einer Nachricht ähnlich wie "Bitte klicken Sie erneut auf ZURÜCK, um zu beenden".

Ich habe mich gefragt, wie ich es immer öfter sehe, ist das eine eingebaute Funktion, die man irgendwie in einer Aktivität nutzen kann? Ich habe mir den Quellcode von vielen Klassen angesehen, aber ich kann nicht scheinen, etwas darüber zu finden.

  • Holen Sie sich die Position von ImageView relativ zum Bildschirm programmgesteuert
  • Kann nicht die genaue aktuelle standort in android finden
  • Bedeutung der blinkenden roten Grenze im Emulator
  • Android Emulator kann nicht gestartet werden
  • Anzeige riesige Bilder in Android
  • Cordova / Phonegap - Android: Icon nicht aktualisiert
  • Natürlich kann ich an ein paar Möglichkeiten denken, die gleiche Funktionalität ganz einfach zu erreichen (am einfachsten ist es wohl, einen Booleschen in der Aktivität zu behalten, der angibt, ob der Benutzer schon einmal geklickt hat …) aber ich habe mich gefragt, ob es hier schon etwas gibt .

    EDIT : Wie @LAS_VEGAS erwähnt, habe ich nicht wirklich "Ausfahrt" in der traditionellen Bedeutung. (Dh beendet) Ich meinte "Rückkehr zu was auch immer war offen, bevor die Anwendung Start Aktivität gestartet wurde", wenn das Sinn macht ๐Ÿ™‚

  • Android-Ressourcen auf einigen Geräten nicht gefunden
  • MediaPlayer stoppt und startet neu
  • Mit Telephony Manager in Android zu finden IMEI-Nummer
  • Live Video Streaming für Android mit Phonegap?
  • GetExternalFilesDir Alternative in Android 2.1
  • Android / Phonegap - onClick () funktioniert nicht
  • 26 Solutions collect form web for “Klicken Sie zweimal auf die Schaltfläche "Zurück", um eine Aktivität zu beenden”

     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 denke, dieser Handler hilft, die Variable nach 2 Sekunden zurückzusetzen.

    Sudheesh B Nair 's hat eine nette (und akzeptierte) Antwort auf die Frage, die ich denke, sollte eine bessere Alternative wie haben;

    Was ist falsch mit der Messzeit vergangen und überprüft, ob TIME_INTERVAL (sagen wir 2000) seit dem letzten zurück drücken. Der folgende Beispielcode verwendet System.currentTimeMillis(); onBackPressed() die Zeit auf onBackPressed() zu speichern, wird aufgerufen;

     private static final int TIME_INTERVAL = 2000; // # milliseconds, desired time passed between two back presses. private long mBackPressed; @Override public void onBackPressed() { if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) { super.onBackPressed(); return; } else { Toast.makeText(getBaseContext(), "Tap back button in order to exit", Toast.LENGTH_SHORT).show(); } mBackPressed = System.currentTimeMillis(); } 

    Zurück auf akzeptierte Antwort Kritik ; Mit einem flag um anzuzeigen, ob es in der letzten TIME_INTERVAL (z. B. 2000) Millisekunden gedrückt wurde und set – reset über Handler 's postDelayed() Methode war das erste, was mir in den Sinn kommt. Aber die postDelayed() -Aktion sollte abgebrochen werden, wenn die Aktivität abgeschlossen ist, wodurch das Runnable .

    Um das Runnable zu entfernen, darf es nicht anonymisiert werden und als Mitglied zusammen mit dem Handler deklariert werden. Dann removeCallbacks() Methode removeCallbacks() von Handler entsprechend aufgerufen werden.

    Die folgende Probe ist die Demonstration;

     private boolean doubleBackToExitPressedOnce; private Handler mHandler = new Handler(); private final Runnable mRunnable = new Runnable() { @Override public void run() { doubleBackToExitPressedOnce = false; } }; @Override protected void onDestroy() { super.onDestroy(); if (mHandler != null) { mHandler.removeCallbacks(mRunnable); } } @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(); mHandler.postDelayed(mRunnable, 2000); } 

    Danke @NSouth zum Mitwirken; Um zu verhindern, dass Toast-Meldung auch nach dem Schließen der Anwendung erscheint, kann Toast als Mitglied – sagen mExitToastmExitToast und kann über mExitToast.cancel(); abgebrochen werden mExitToast.cancel(); Kurz vor super.onBackPressed(); Anruf.

    Ich dachte nur, ich würde teilen, wie ich es am Ende getan habe, ich habe gerade meine Tätigkeit hinzugefügt:

     private boolean doubleBackToExitPressedOnce = false; @Override protected void onResume() { super.onResume(); // .... other stuff in my onResume .... this.doubleBackToExitPressedOnce = false; } @Override public void onBackPressed() { if (doubleBackToExitPressedOnce) { super.onBackPressed(); return; } this.doubleBackToExitPressedOnce = true; Toast.makeText(this, R.string.exit_press_back_twice_message, Toast.LENGTH_SHORT).show(); } 

    Und es funktioniert genau so wie ich will. Einschließlich der Rückstellung des Staates, wenn die Aktivität wieder aufgenommen wird.

    Ablaufdiagramm: Zum Verlassen erneut drücken.

    Java-Code:

     private long lastPressedTime; private static final int PERIOD = 2000; @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { switch (event.getAction()) { case KeyEvent.ACTION_DOWN: if (event.getDownTime() - lastPressedTime < PERIOD) { finish(); } else { Toast.makeText(getApplicationContext(), "Press again to exit.", Toast.LENGTH_SHORT).show(); lastPressedTime = event.getEventTime(); } return true; } } return false; } 

    Basierend auf der richtigen Antwort und Anregungen in Kommentaren, habe ich eine Demo erstellt, die absolut gut funktioniert und entfernt die Handler Rückrufe nach der Verwendung.

    MainActivity.java

     package com.mehuljoisar.d_pressbacktwicetoexit; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.widget.Toast; public class MainActivity extends Activity { private static final long delay = 2000L; private boolean mRecentlyBackPressed = false; private Handler mExitHandler = new Handler(); private Runnable mExitRunnable = new Runnable() { @Override public void run() { mRecentlyBackPressed=false; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void onBackPressed() { //You may also add condition if (doubleBackToExitPressedOnce || fragmentManager.getBackStackEntryCount() != 0) // in case of Fragment-based add if (mRecentlyBackPressed) { mExitHandler.removeCallbacks(mExitRunnable); mExitHandler = null; super.onBackPressed(); } else { mRecentlyBackPressed = true; Toast.makeText(this, "press again to exit", Toast.LENGTH_SHORT).show(); mExitHandler.postDelayed(mExitRunnable, delay); } } } 

    Ich hoffe es wird hilfreich sein !!

    Es gibt sehr einfachste Weg unter all diesen Antworten.

    Schreiben Sie einfach den folgenden Code innerhalb der onBackPressed() Methode.

     @Override public void onBackPressed() { if (back_pressed + 1000 > System.currentTimeMillis()){ super.onBackPressed(); } else{ Toast.makeText(getBaseContext(), "Press once again to exit!", Toast.LENGTH_SHORT) .show(); } back_pressed = System.currentTimeMillis(); } 

    Sie müssen back_pressed Objekt so long in Aktivität definieren.

    Es ist keine gute Idee, einen Runnable zu verwenden, wenn du die Anwendung beendest, habe ich vor kurzem eine viel einfachere Art und Weise zum Aufnehmen und Vergleichen der Periode zwischen zwei BACK Button Klicks. Beispielcode wie folgt:

     private static long back_pressed_time; private static long PERIOD = 2000; @Override public void onBackPressed() { if (back_pressed_time + PERIOD > System.currentTimeMillis()) super.onBackPressed(); else Toast.makeText(getBaseContext(), "Press once again to exit!", Toast.LENGTH_SHORT).show(); back_pressed_time = System.currentTimeMillis(); } 

    Dies wird der Trick, um die Anwendung durch eine doppelte BACK-Taste zu verlassen Klicks innerhalb einer bestimmten Verzögerungszeit, die 2000 Millisekunden in Probe ist.

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

    Deklarieren Variable private boolean doubleBackToExitPressedOnce = false;

    Fügen Sie diese in Ihre Hauptaktivität ein und dies wird Ihr Problem lösen

    "

    Es ist keine eingebaute Funktionalität. Ich denke, es ist nicht einmal das empfohlene Verhalten. Android-Apps sollen nicht beenden:

    Warum nicht Android-Anwendungen bieten eine "Exit" -Option?

    Ich weiß, das ist eine sehr alte Frage, aber das ist der einfachste Weg zu tun, was Sie wollen.

     @Override public void onBackPressed() { ++k; //initialise k when you first start your activity. if(k==1){ //do whatever you want to do on first click for example: Toast.makeText(this, "Press back one more time to exit", Toast.LENGTH_LONG); }else{ //do whatever you want to do on the click after the first for example: finish(); } } 

    Ich weiß, das ist nicht die beste Methode, aber es geht gut!

    Zefnus 'Antwort mit System.currentTimeMillis () ist die beste (+1). Die Art, wie ich es tat, ist nicht besser als das, aber immer noch Posting, um die oben genannten Ideen hinzuzufügen.

    Wenn der Toast nicht sichtbar ist, wenn die Toast.LENGTH_SHORT gedrückt wird, wird der Toast angezeigt, wohingegen, wenn er sichtbar ist (die Rückseite wurde bereits einmal in der letzten Toast.LENGTH_SHORT Zeit gedrückt), dann wird es verlassen.

     exitToast = Toast.makeText(this, "Press again to exit", Toast.LENGTH_SHORT); . . @Override public void onBackPressed() { if (exitToast.getView().getWindowToken() == null) //if toast is currently not visible exitToast.show(); //then show toast saying 'press againt to exit' else { //if toast is visible then finish(); //or super.onBackPressed(); exitToast.cancel(); } } 

    Kürzlich musste ich diese Back-Button-Funktion in einer App von mir zu implementieren. Die Antworten auf die ursprüngliche Frage waren nützlich, aber ich musste noch zwei Punkte berücksichtigen:

    1. Zu einem bestimmten Zeitpunkt ist die Rücktaste deaktiviert
    2. Die Hauptaktivität ist die Verwendung von Fragmenten in Kombination mit einem Backstack

    Basierend auf den Antworten und Kommentaren habe ich folgenden Code erstellt:

     private static final long BACK_PRESS_DELAY = 1000; private boolean mBackPressCancelled = false; private long mBackPressTimestamp; private Toast mBackPressToast; @Override public void onBackPressed() { // Do nothing if the back button is disabled. if (!mBackPressCancelled) { // Pop fragment if the back stack is not empty. if (getSupportFragmentManager().getBackStackEntryCount() > 0) { super.onBackPressed(); } else { if (mBackPressToast != null) { mBackPressToast.cancel(); } long currentTimestamp = System.currentTimeMillis(); if (currentTimestamp < mBackPressTimestamp + BACK_PRESS_DELAY) { super.onBackPressed(); } else { mBackPressTimestamp = currentTimestamp; mBackPressToast = Toast.makeText(this, getString(R.string.warning_exit), Toast.LENGTH_SHORT); mBackPressToast.show(); } } } } 

    Der obige Code setzt voraus, dass die Supportbibliothek verwendet wird. Wenn Sie Fragmente verwenden, aber nicht die Supportbibliothek, müssen Sie getSupportFragmentManager() von getFragmentManager() ersetzen.

    Entfernen Sie die erste, wenn die Rücktaste niemals abgebrochen wird. Entfernen Sie die zweite, if , wenn Sie nicht verwenden Fragmente oder ein Fragment zurück Stapel

    Außerdem ist es wichtig zu wissen, dass die Methode onBackPressed seit Android 2.0 unterstützt wird. Überprüfen Sie diese Seite auf eine ausführliche Beschreibung. Um die Back-Press-Funktion auch auf ältere Versionen zu machen, füge die folgende Methode zu deiner Aktivität hinzu:

     @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR && keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { // Take care of calling this method on earlier versions of // the platform where it doesn't exist. onBackPressed(); } return super.onKeyDown(keyCode, event); } 

    Die Akzeptierte Antwort ist die beste, aber wenn Sie Android Design Support Library dann können Sie SnackBar für bessere Ansichten verwenden.

      boolean doubleBackToExitPressedOnce = false; @Override public void onBackPressed() { if (doubleBackToExitPressedOnce) { super.onBackPressed(); return; } this.doubleBackToExitPressedOnce = true; Snackbar.make(findViewById(R.id.photo_album_parent_view), "Please click BACK again to exit", Snackbar.LENGTH_SHORT).show(); new Handler().postDelayed(new Runnable() { @Override public void run() { doubleBackToExitPressedOnce=false; } }, 2000); } 
     @Override public void onBackPressed() { Log.d("CDA", "onBackPressed Called"); Intent intent = new Intent(); intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); startActivity(intent); } 
    1. Deklariere eine globale Toastvariable für die MainActivity Class. Beispiel: Toast exitToast;
    2. Initialize es in onCreate Ansicht Methode. Beispiel: exitToast = Toast.makeText (getApplicationContext (), "Zurück zum Beenden drücken", Toast.LENGTH_SHORT);
    3. Schließlich erstellen Sie eine onBackPressedMethod wie folgt:

       @Override public void onBackPressed() { if (exitToast.getView().isShown()) { exitToast.cancel(); finish(); } else { exitToast.show(); } } 

    Das funktioniert richtig, ich habe getestet. Und ich denke das ist viel einfacher.

    Zu diesem Zweck habe ich folgende Funktion implementiert:

     private long onRecentBackPressedTime; @Override public void onBackPressed() { if (System.currentTimeMillis() - onRecentBackPressedTime > 2000) { onRecentBackPressedTime = System.currentTimeMillis(); Toast.makeText(this, "Please press BACK again to exit", Toast.LENGTH_SHORT).show(); return; } super.onBackPressed(); } 

    Meine Lösung mit Snackbar:

     LinearLayout layout; Snackbar snackbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); layout = (LinearLayout) findViewById(R.id.layout_main); snackbar = snackbar.make(layout, R.string.press_back_again, Snackbar.LENGTH_LONG); } @Override public void onBackPressed() { if(snackbar.isShown()) { super.onBackPressed(); } else { snackbar.show(); } } 

    Hier ist der volle Arbeitscode. Und auch nicht vergessen, die Rückrufe zu entfernen, so dass es keinen Speicherverlust in der App verursacht. ๐Ÿ™‚

     private boolean backPressedOnce = false; private Handler statusUpdateHandler; private Runnable statusUpdateRunnable; public void onBackPressed() { if (backPressedOnce) { finish(); } backPressedOnce = true; final Toast toast = Toast.makeText(this, "Press again to exit", Toast.LENGTH_SHORT); toast.show(); statusUpdateRunnable = new Runnable() { @Override public void run() { backPressedOnce = false; toast.cancel(); //Removes the toast after the exit. } }; statusUpdateHandler.postDelayed(statusUpdateRunnable, 2000); } @Override protected void onDestroy() { super.onDestroy(); if (statusUpdateHandler != null) { statusUpdateHandler.removeCallbacks(statusUpdateRunnable); } } 

    Dies ist auch hilfreich, wenn Sie vorherigen Stack-Aktivitätsspeicher im Stack haben.

    Ich habe die Antwort von Sudheesh geändert

     boolean doubleBackToExitPressedOnce = false; @Override public void onBackPressed() { if (doubleBackToExitPressedOnce) { //super.onBackPressed(); Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//***Change Here*** startActivity(intent); finish(); System.exit(0); 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); } 

    Dies ist das gleiche von der akzeptierten und die meisten Stimmen Antwort, aber diese Snipped verwendet Snackbar statt Toast.

     boolean doubleBackToExitPressedOnce = false; @Override public void onBackPressed() { if (doubleBackToExitPressedOnce) { super.onBackPressed(); return; } this.doubleBackToExitPressedOnce = true; Snackbar.make(content, "Please click BACK again to exit", Snackbar.LENGTH_SHORT) .setAction("Action", null).show(); new Handler().postDelayed(new Runnable() { @Override public void run() { doubleBackToExitPressedOnce=false; } }, 2000); } 
     boolean doubleBackToExitPressedOnce = false; @Override public void onBackPressed() { if (doubleBackToExitPressedOnce) { super.onBackPressed(); return; } this.doubleBackToExitPressedOnce = true; Snackbar.make(findViewById(R.id.photo_album_parent_view), "Please click BACK again to exit", Snackbar.LENGTH_SHORT).show(); new Handler().postDelayed(new Runnable() { @Override public void run() { doubleBackToExitPressedOnce=false; } }, 2000); } 

    Einige Verbesserungen in der Antwort von Sudheesh B Nair, ich habe bemerkt, dass es auf den Handler warten wird, auch wenn er zweimal sofort gedrückt wird, also den Handler wie unten gezeigt abbrechen. Ich habe auch Toast gekippt, um zu verhindern, dass es nach der App-Ausfahrt angezeigt wird.

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

    Eine etwas bessere Methode als Zefnus denke ich. Rufen Sie System.currentTimeMillis () nur einmal auf und lassen Sie die return; :

     long previousTime; @Override public void onBackPressed() { if (2000 + previousTime > (previousTime = System.currentTimeMillis())) { super.onBackPressed(); } else { Toast.makeText(getBaseContext(), "Tap back button in order to exit", Toast.LENGTH_SHORT).show(); } } 

    In meinem Fall bin ich auf Snackbar#isShown() für besseres UX angewiesen.

     private Snackbar exitSnackBar; @Override public void onBackPressed() { if (isNavDrawerOpen()) { closeNavDrawer(); } else if (getSupportFragmentManager().getBackStackEntryCount() == 0) { if (exitSnackBar != null && exitSnackBar.isShown()) { super.onBackPressed(); } else { exitSnackBar = Snackbar.make( binding.getRoot(), R.string.navigation_exit, 2000 ); exitSnackBar.show(); } } else { super.onBackPressed(); } } 

    Für die Aktivität, deren Navigations-Schublade ist , verwenden Sie den folgenden Code für OnBackPressed ()

     boolean doubleBackToExitPressedOnce = false; @Override public void onBackPressed() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { if (doubleBackToExitPressedOnce) { if (getFragmentManager().getBackStackEntryCount() ==0) { finishAffinity(); System.exit(0); } else { getFragmentManager().popBackStackImmediate(); } return; } if (getFragmentManager().getBackStackEntryCount() ==0) { 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); } else { getFragmentManager().popBackStackImmediate(); } } } 
      int back = 1; @Override public void onBackPressed(){ if(back==2) { super.onBackPressed(); } else{ Toast.makeText(this,"Press back again to close",Toast.LENGTH_SHORT).show(); back++; } } 

    Wenn du einfach gehen möchtest, ohne dich mit einem komplizierten Code zu verwirren, versuchst du diese Methode.

    Das Android ist ein Google Android Fan-Website, Alles รผber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.