it-swarm.com.de

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

Ich habe dieses Muster in letzter Zeit bei vielen Android-Apps und -Spielen festgestellt: Wenn Sie auf die Zurück-Schaltfläche klicken, um die Anwendung zu "beenden", erscheint eine Toast-Nachricht mit der Meldung "Bitte klicken Sie erneut auf ZURÜCK, um den Vorgang zu beenden".

Ich habe mich gefragt, wie ich es immer öfter sehe, ist dies eine integrierte Funktion, auf die Sie irgendwie in einer Aktivität zugreifen können? Ich habe mir den Quellcode vieler Klassen angesehen, aber ich finde anscheinend nichts darüber.

Natürlich kann ich über einige Wege nachdenken, um die gleiche Funktionalität recht einfach zu erreichen (am einfachsten ist es wahrscheinlich, ein boolesches Element beizubehalten, das angibt, ob der Benutzer bereits einmal geklickt hat ...), aber ich habe mich gefragt, ob hier schon etwas ist .

EDIT: Wie @LAS_VEGAS erwähnt, meinte ich nicht wirklich "Exit" im traditionellen Sinn. (d. h. beendet) Ich meinte "zurück zu dem, was vor dem Start der Anwendungsaktivität geöffnet war", wenn dies sinnvoll ist :)

278
Guillaume

In Java-Aktivität:

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

In Kotlin-Aktivität:

private var doubleBackToExitPressedOnce = false
override fun onBackPressed() {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed()
            return
        }

        this.doubleBackToExitPressedOnce = true
        Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show()

        Handler().postDelayed(Runnable { doubleBackToExitPressedOnce = false }, 2000)
    }

Ich denke, dieser Handler hilft, die Variable nach 2 Sekunden zurückzusetzen.

815
Sudheesh B Nair

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

Was ist falsch daran, die abgelaufene Zeit zu messen und zu überprüfen, ob TIME_INTERVAL Millisekunden (z. B. 2000) seit dem letzten Zurückdrücken vergangen sind. Im folgenden Beispielcode wird mit System.currentTimeMillis(); die Uhrzeit gespeichert, zu der onBackPressed() aufgerufen wird.

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 zur akzeptierten Antwort Kritik; Verwenden Sie ein flag, um anzuzeigen, ob es in den letzten TIME_INTERVAL (Z. B. 2000) Millisekunden gedrückt wurde, und set - reset ist über die postDelayed() - Methode von Handler gekommen. Die Aktion postDelayed() sollte jedoch abgebrochen werden, wenn die Aktivität beendet wird und Runnable entfernt wird.

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

Das folgende Beispiel 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);
}

Vielen Dank an @NSouth für Ihren Beitrag. Um zu verhindern, dass toast message auch nach dem Schließen der Anwendung angezeigt wird, kann Toast als Mitglied deklariert werden - sagen wir mExitToast - und über mExitToast.cancel(); kurz vor dem Aufruf von super.onBackPressed();.

210
Saro Taşciyan

Ich dachte nur, ich würde erzählen, wie ich es am Ende getan habe. Ich fügte nur hinzu:

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 es will. Einschließlich des Zurücksetzens des Status bei jeder Wiederaufnahme der Aktivität.

28
Guillaume

Ablaufdiagramm: Press again to exit.

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;
}
24
vHow

Unter all diesen Antworten gibt es einen sehr einfachen Weg.

Schreiben Sie einfach folgenden Code in die onBackPressed()-Methode.

long back_pressed;

@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 das back_pressed-Objekt in der Aktivität als long definieren.

18
Chintan Rathod

Basierend auf der richtigen Antwort und den Vorschlägen in Kommentaren habe ich eine Demo erstellt, die absolut einwandfrei funktioniert und die Handler-Rückrufe nach der Verwendung entfernt.

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 !!

12
Mehul Joisar

Meine Lösung mit Snackbar:

Snackbar mSnackbar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final LinearLayout layout = findViewById(R.id.layout_main);
    mSnackbar = Snackbar.make(layout, R.string.press_back_again, Snackbar.LENGTH_SHORT);
}

@Override
public void onBackPressed() {
    if (mSnackbar.isShown()) {
        super.onBackPressed();
    } else {
        mSnackbar.show();
    }
}

Einfach und stilvoll.

11
Hugo Passos
 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);

Variable deklarieren private boolean doubleBackToExitPressedOnce = false;

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

10
Rakshith

Es ist keine gute Idee, beim Beenden der Anwendung ein lauffähiges Programm zu verwenden. Ich habe kürzlich herausgefunden, dass es viel einfacher ist, den Zeitraum zwischen zwei Klicks mit der BACK-Taste aufzuzeichnen und zu vergleichen. 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 bewirkt den Trick, die Anwendung durch zweimaliges Klicken der BACK-Taste innerhalb einer bestimmten Verzögerungszeit zu beenden, die 2000 Millisekunden beträgt.

9
Max Lee

Die akzeptierte Antwort ist die Beste, aber wenn Sie Android Design Support Library verwenden, 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);
    }
6
Pratik Butani

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

Warum bieten Android-Anwendungen keine Option zum Beenden?

6
Caner
  1. Deklarieren Sie eine globale Toast-Variable für die MainActivity-Klasse. Beispiel: Toast exitToast;
  2. Initialisieren Sie es in der OnCreate-Ansichtsmethode. Beispiel: exitToast = Toast.makeText (getApplicationContext (), "Zum Verlassen erneut drücken", Toast.LENGTH_SHORT);
  3. Erstellen Sie abschließend eine onBackPressedMethod wie folgt:

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

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

6
Supto

Vor kurzem musste ich diese Back-Button-Funktion in einer meiner App implementieren. Die Antworten auf die ursprüngliche Frage waren nützlich, aber ich musste zwei weitere Punkte berücksichtigen:

  1. Zu einigen Zeitpunkten ist die Zurück-Taste deaktiviert
  2. Die Hauptaktivität besteht in der Verwendung von Fragmenten in Kombination mit einem Backstack

Basierend auf den Antworten und Kommentaren habe ich den 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 Unterstützungsbibliothek verwendet wird. Wenn Sie Fragmente verwenden, jedoch nicht die Unterstützungsbibliothek, möchten Sie getSupportFragmentManager() durch getFragmentManager() ersetzen.

Entfernen Sie die erste if, wenn die Zurück-Schaltfläche nie abgebrochen wird. Entfernen Sie die zweite if, wenn Sie keine Fragmente oder einen Fragment-Back-Stack verwenden

Es ist auch wichtig zu wissen, dass die Methode onBackPressed seit Android 2.0 unterstützt wird. Überprüfen Sie diese Seite für eine ausführliche Beschreibung. Damit die Back-Press-Funktion auch bei älteren Versionen funktioniert, fügen Sie Ihrer Aktivität die folgende Methode 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);
}
5
Tomasz Nguyen

Ich weiß, dass dies eine sehr alte Frage ist, aber dies ist der einfachste Weg, um das 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).show();
   }else{
      //do whatever you want to do on the click after the first for example:
      finish(); 
   }
}

Ich weiß, dass dies nicht die beste Methode ist, aber es funktioniert gut!

4

Die Antwort von Zefnus mit System.currentTimeMillis () ist die beste (+1). Die Art und Weise, wie ich es gemacht habe, ist nicht besser als das, aber trotzdem veröffentlicht, um es den obigen Ideen hinzuzufügen.

Wenn der Toast beim Drücken der Zurück-Taste nicht sichtbar ist, wird der Toast angezeigt. Wenn er sichtbar ist (die Rückseite wurde bereits einmal innerhalb der letzten Toast.LENGTH_SHORT-Zeit gedrückt), wird der Toast beendet.

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

Dies ist auch hilfreich, wenn Sie vorherige Stapelaktivitäten im Stapel gespeichert haben. 

Ich habe Sudheeshs Antwort modifiziert 

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);
} 
3
Arpit Patel

Hier habe ich verallgemeinernd den Code für N Tapcounts geschrieben. Der Code ist in ähnlicher Weise für die Option Entwickler aktivieren im Telefon eines Android-Geräts geschrieben. Sogar Sie können dies verwenden, um Funktionen zu aktivieren, während der Entwickler die App testet.

 private Handler tapHandler;
 private Runnable tapRunnable;
 private int mTapCount = 0;
 private int milSecDealy = 2000;

onCreate(){
 ...
tapHandler = new Handler(Looper.getMainLooper());

 }

Call askToExit () bei der Option zum Zurückdrücken oder Abmelden.

private void askToExit() {
   if (mTapCount >= 2) {
    releaseTapValues();
    /* ========= Exit = TRUE  =========  */
   }

   mTapCount++;
   validateTapCount();
  }


  /* Check with null to avoid create multiple instances of the runnable */
  private void validateTapCount() {
   if (tapRunnable == null) {
    tapRunnable = new Runnable() {
     @Override
     public void run() {
      releaseTapValues();
      /* ========= Exit = FALSE  =========  */
     }
    };
    tapHandler.postDelayed(tapRunnable, milSecDealy);
   }
  }

  private void releaseTapValues() {
   /* Relase the value  */
   if (tapHandler != null) {
    tapHandler.removeCallbacks(tapRunnable);
    tapRunnable = null; /* release the object */
    mTapCount = 0; /* release the value */
   }
  }


  @Override
  protected void onDestroy() {
   super.onDestroy();
   releaseTapValues();
  }
2
Chintan Khetiya
@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);
}
2
Aditya_Android

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

Wenn HomeActivity die Navigationsleiste und die Funktion double backPressed () enthält, um app .. zu beenden. (Vergessen Sie nicht, die globale Variable zu initialisieren.) Boolean doubleBackToExitPressedOnce = false;) Neuer Handler nach 2 Sekunden 

@Override
public void onBackPressed() {
    DrawerLayout drawer = findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.END)) {
        drawer.closeDrawer(GravityCompat.END);
    } else {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed();
            moveTaskToBack(true);
            return;
        } else {
            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);
        }
    }
}
2
Abhishek S

In Java

private Boolean exit = false; 

if (exit) {
onBackPressed(); 
}

 @Override
public void onBackPressed() {
    if (exit) {
        finish(); // finish activity
    } else {
        Toast.makeText(this, "Press Back again to Exit.",
                Toast.LENGTH_SHORT).show();
        exit = true;
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                exit = false;
            }
        }, 3 * 1000);

    }
}

in kotlin

 private var exit = false

 if (exit) {
        onBackPressed()
         }

 override fun onBackPressed(){
           if (exit){
               finish() // finish activity
           }else{
            Toast.makeText(this, "Press Back again to Exit.",
                    Toast.LENGTH_SHORT).show()
            exit = true
            Handler().postDelayed({ exit = false }, 3 * 1000)

        }
    }
2
Praveen

Hier ist der vollständige Arbeitscode. Vergessen Sie auch nicht, die Rückrufe zu entfernen, damit in der App kein Speicherverlust entsteht. :) 

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);
    }
}
2
Saket Kumar

Normalerweise würde ich einen Kommentar hinzufügen, aber mein Ruf lässt dies nicht zu. Hier also meine zwei Cents:

In Kotlin können Sie Coroutines verwenden, um die Einstellung auf false zu verzögern:

private var doubleBackPressed = false
private var toast : Toast ?= null

override fun onCreate(savedInstanceState: Bundle?) {
    toast = Toast.maketext(this, "Press back again to exit", Toast.LENGTH_SHORT)
}

override fun onBackPressed() {
    if (doubleBackPressed) {
        toast?.cancel()
        super.onBackPressed()
        return
    }
    this.doubleBackPressed = true
    toast?.show()
    GlobalScope.launch {
        delay(2000)
        doubleBackPressed = false
    }
}

Sie müssen importieren:

import kotlinx.coroutines.launch
import kotlinx.coroutines.delay
import kotlinx.coroutines.GlobalScope
1
DannyRitiu

Einige Verbesserungen in Sudheesh B Nairs Antwort, ich habe bemerkt, dass der Handler warten wird, auch wenn er gleich zweimal zurückgedrückt wird. Ich habe den Toast auch deaktiviert, um zu verhindern, dass er nach dem Beenden der App 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);
        }
1
Divyang Panchal

In dieser Situation ist Snackbar die bessere Option als Toast, um die Beendigungsaktion anzuzeigen. Hier ist die Methode mit Snackbar, die funktioniert.

@Override
        public void onBackPressed() {
            if (doubleBackToExitPressedOnce) {
                super.onBackPressed();
                return;
            }
            this.doubleBackToExitPressedOnce = true;
            Snackbar.make(this.getWindow().getDecorView().findViewById(Android.R.id.content), "Please click BACK again to exit", Snackbar.LENGTH_SHORT).show();

            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {
                    doubleBackToExitPressedOnce=false;
                }
            }, 2000);
        }
1
Mitkumar Patel

Dies ist das Gleiche wie die akzeptierte und am meisten gewählte Antwort, aber bei diesem Ausschnitt wurde Snackbar anstelle von Toast verwendet.

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);
    }
1
MobileOS

Verwenden Sie den folgenden Code für die Aktivität, deren Navigation Drawer ist.

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

Hier ist ein anderer Weg ... mit der Methode CountDownTimer

private boolean exit = false;
@Override
public void onBackPressed() {
        if (exit) {
            finish();
        } else {
            Toast.makeText(this, "Press back again to exit",
                    Toast.LENGTH_SHORT).show();
            exit = true;
            new CountDownTimer(3000,1000) {

                @Override
                public void onTick(long l) {

                }

                @Override
                public void onFinish() {
                    exit = false;
                }
            }.start();
        }

    }
1
Anuj Sain
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);
}
1
maniix

Ich benutze das

import Android.app.Activity;
import Android.support.annotation.StringRes;
import Android.widget.Toast;

public class ExitApp {

    private static long lastClickTime;

    public static void now(Activity ctx, @StringRes int message) {
        now(ctx, ctx.getString(message), 2500);
    }

    public static void now(Activity ctx, @StringRes int message, long time) {
        now(ctx, ctx.getString(message), time);
    }

    public static void now(Activity ctx, String message, long time) {
        if (ctx != null && !message.isEmpty() && time != 0) {
            if (lastClickTime + time > System.currentTimeMillis()) {
                ctx.finish();
            } else {
                Toast.makeText(ctx, message, Toast.LENGTH_SHORT).show();
                lastClickTime = System.currentTimeMillis();
            }
        }
    }

}

mit to in event onBackPressed

@Override
public void onBackPressed() {
   ExitApp.now(this,"Press again for close");
}

oder ExitApp.now(this,R.string.double_back_pressed)

für die Änderung benötigen Sekunden für das Schließen festgelegte Millisekunden

ExitApp.now(this,R.string.double_back_pressed,5000)

1
Webserveis

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

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();
    }
}
1
Khoa Chu Anh

In meinem Fall bin ich auf Snackbar#isShown() angewiesen, um UX besser zu nutzen.

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

In Kotlin auf der Rückseite drücken, um die App zu beenden:

Definieren Sie eine globale Variable:

private var doubleBackToExitPressedOnce = false

OnBackPressed überschreiben:

override fun onBackPressed() {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed()
            return
        }

        doubleBackToExitPressedOnce = true
        Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_LONG).show()

        Handler().postDelayed({
            doubleBackToExitPressedOnce = false;
        }, 2000)
    }
0
Shylendra Madda

Sie können auch die Sichtbarkeit eines Toast nutzen, so dass Sie diese Handler/postDelayed-Ultra-Lösung nicht benötigen.

Toast doubleBackButtonToast;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    doubleBackButtonToast = Toast.makeText(this, "Double tap back to exit.", Toast.LENGTH_SHORT);
}

@Override
public void onBackPressed() {
    if (doubleBackButtonToast.getView().isShown()) {
        super.onBackPressed();
    }

    doubleBackButtonToast.show();
}
0
Hudson Pereira

Zurück, wenn die Taste zweimal gedrückt wurde 

public void click(View view){
    if (isBackActivated) {
        this.finish();
    }
    if (!isBackActivated) {
        isBackActivated = true;
        Toast.makeText(getApplicationContext(), "Again", Toast.LENGTH_SHORT).show();
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                isBackActivated = false;  // setting isBackActivated after 2 second
            }
        }, 2000);
    }

}
0
private static final int TIME_INTERVAL = 2000;
private long mBackPressed;
    @Override
        public void onBackPressed() {

            if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) {
                super.onBackPressed();
                Intent intent = new Intent(FirstpageActivity.this,
                        HomepageActivity.class);
                startActivity(intent);
                finish();

                return;
            } else {

                Toast.makeText(getBaseContext(),
                        "Tap back button twice  to go Home.", Toast.LENGTH_SHORT)
                        .show();

                mBackPressed = System.currentTimeMillis();

            }

        }
0
Umesh Maharjan

Beste Lösung mit Toast

In Java

private Toast exitToast;

@Override
public void onBackPressed() {
    if (exitToast == null || exitToast.getView() == null || exitToast.getView().getWindowToken() == null) {
        exitToast = Toast.makeText(this, "Press again to exit", Toast.LENGTH_LONG);
        exitToast.show();
    } else {
        exitToast.cancel();
        super.onBackPressed();
    }
}

In Kotlin

private var exitToast: Toast? = null

override fun onBackPressed() {
    if (exitToast == null || exitToast!!.view == null || exitToast!!.view.windowToken == null) {
        exitToast = Toast.makeText(this, "Press again to exit", Toast.LENGTH_LONG)
        exitToast!!.show()
    } else {
        exitToast!!.cancel()
        super.onBackPressed()
    }
}
0

Hier ist meine Meinung dazu:

 int oddeven = 0;
 long backBtnPressed1;
 long backBtnPressed2;
 @Override
 public void onBackPressed() {
     oddeven++;
     if(oddeven%2==0){
         backBtnPressed2 = System.currentTimeMillis();
         if(backBtnPressed2-backBtnPressed1<2000) {
            super.onBackPressed();
            return;
         }
     }
     else if(oddeven%2==1) { 
         backBtnPressed1 = System.currentTimeMillis();    
        //  Insert toast back button here
     }
 }
0
R41N
 private static final int TIME_DELAY = 2000;
    private static long back_pressed;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    public void onBackPressed() {
        if (back_pressed + TIME_DELAY > System.currentTimeMillis()) {
            super.onBackPressed();
        } else {
            Toast.makeText(getBaseContext(), "Press once again to exit!",
                    Toast.LENGTH_SHORT).show();
        }
        back_pressed = System.currentTimeMillis();
    }
0
Avinash

Nachdem die gleichen Dinge viele Male implementiert werden mussten, entschied sich jemand, eine einfach zu benutzende Bibliothek zu bauen. Und das ist DoubleBackPress Android library . Die Variable README erläutert alle APIs, die zusammen mit den Beispielen (wie ToastDisplay + Exit Activity ) bereitgestellt werden, jedoch nur einen kurzen Überblick über die Schritte hier.


Um loszulegen, fügen Sie Ihrer Anwendung die dependency hinzu:

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

Als Nächstes erstellen Sie ein DoubleBackPress-Objekt in Ihrer Activity, das das erforderliche Verhalten bereitstellt.

DoubleBackPress doubleBackPress = new DoubleBackPress();
doubleBackPress.setDoublePressDuration(3000);           // msec

Erstellen Sie dann eine Toast, die beim First Back angezeigt werden muss. Drücken Sie. Hier können Sie Ihre eigene Toast erstellen oder mit Standard Toast in der library fortfahren. Dies hier durch die spätere Option.

FirstBackPressAction firstBackPressAction = new ToastDisplay().standard(this);
doubleBackPress.setFirstBackPressAction(firstBackPressAction);   // set the action

Definieren Sie nun, was passieren soll, wenn Ihre zweite Rückpressung erfolgt. Hier schließen wir die Aktivität.

DoubleBackPressAction doubleBackPressAction = new DoubleBackPressAction() {
    @Override
    public void actionCall() {
        finish();
        System.exit(0);
    }
};

Überschreiben Sie schließlich Ihr Verhalten beim Backpress mit dem Verhalten DoubleBackPress.

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

Beispiel-GIF mit ähnlichen Verhaltensanforderungen

0
Kaushik NP

sie können es sogar einfacher machen, und ohne einen Hander zu tun, tun Sie dies nur =) 

Long firstClick = 1L;
Long secondClick = 0L;

@Override
public void onBackPressed() {
secondClick = System.currentTimeMillis();
    if ((secondClick - firstClick) / 1000 < 2) {
          super.onBackPressed();
    } else {
          firstClick = System.currentTimeMillis();
          Toast.makeText(MainActivity.this, "click BACK again to exit", Toast.LENGTH_SHORT).show();
        }
 }
0
G. Adnane

Hier ist eine Möglichkeit, dies mit RxJava zu tun:

override fun onCreate(...) {
    backPresses.timeInterval(TimeUnit.MILLISECONDS, Schedulers.io())
            .skip(1) //Skip initial event; delay will be 0.
            .onMain()
            .subscribe {
                if (it.time() < 7000) super.onBackPressed() //7000 is the duration of a Toast with length LENGTH_LONG.
            }.addTo(compositeDisposable)

    backPresses.throttleFirst(7000, TimeUnit.MILLISECONDS, Schedulers.io())
            .subscribe { Toast.makeText(this, "Press back again to exit.", LENGTH_LONG).show() }
            .addTo(compositeDisposable)
}

override fun onBackPressed() = backPresses.onNext(Unit)
0
urgentx

Ich denke, das ist was du brauchst, ich meine, wenn wir diesen Toast zeigen wollen, wenn es nur eine Aktivität im Stapel gibt und der Benutzer zurück drückt von dieser letzten Aktivität des Stapels.

var exitOpened=false // Declare it globaly

und in der onBackPressed Methode ändere es wie folgt:

override fun onBackPressed() {
        if (isTaskRoot && !exitOpened)
        {
            exitOpened=true
            toast("Please press back again to exit")
            return
        }
        super.onBackPressed()
    }

Hier gibt isTaskRoot true zurück, wenn die aktuelle Aktivität die Root-Aktivität (erste Aktivität) des Stacks ist, und false, wenn dies nicht der Fall ist.

Sie können die offiziellen Unterlagen einsehen hier

0
Suraj Vaishnav