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 :)
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.
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();
.
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.
Ablaufdiagramm:
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;
}
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.
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 !!
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.
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
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.
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);
}
Es ist keine eingebaute Funktionalität. Ich denke es ist nicht einmal das empfohlene Verhalten. Android-Apps sollen nicht beendet werden:
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.
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:
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);
}
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!
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();
}
}
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);
}
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();
}
@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);
}
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();
}
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);
}
}
}
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)
}
}
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);
}
}
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
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);
}
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);
}
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);
}
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();
}
}
}
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();
}
}
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);
}
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)
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();
}
}
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();
}
}
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)
}
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();
}
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);
}
}
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();
}
}
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()
}
}
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
}
}
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();
}
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();
}
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();
}
}
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)
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