web-dev-qa-db-ja.com

アクティビティを終了するには、戻るボタンを2回クリックします

最近、多くのAndroidアプリやゲームでこのパターンに気付いた。アプリケーションを「終了」するために戻るボタンをクリックすると、Toastに「もう一度戻るにはもう一度クリックしてください」というようなメッセージが表示されます。

私はそれがますます頻繁に見ているように、あなたがどういうわけかあなたが活動の中でアクセスすることができる組み込みの機能であるということを疑問に思いましたか?私は多くのクラスのソースコードを調べましたが、それについて何かを見つけることができないようです。

もちろん、同じ機能を非常に簡単に達成するためのいくつかの方法を考えることができます(最も簡単な方法は、ユーザーが既に1回クリックしたかどうかを示すブール値を保持することです)。 。

EDIT:@LAS_VEGASが述べたように、私は伝統的な意味で「終了」を意味しませんでした。それが理にかなっているなら、私は「アプリケーション開始アクティビティが開始される前に開いていたものに戻る」という意味でした:)

297
Guillaume

Javaアクティビティの場合:

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

コトリン活動中:

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

このハンドラは2秒後に変数をリセットするのに役立ちます。

849
Sudheesh B Nair

Sudheesh B Nair は、この質問に対していい(そして受け入れられた)答えを持っています。

経過時間を測定し、最後のバックプレスからTIME_INTERVALミリ秒(2000など)が経過したかどうかをチェックすることの問題は何ですか。次のサンプルコードは、System.currentTimeMillis();が呼び出された時間を格納するためにonBackPressed()を使用します。

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

承認された回答に戻るcritique;最後のTIME_INTERVAL(2000など)で押されたかどうかを示すためにflagNAME _を使用し、set - resetを介してHandlername__を使用するpostDelayed() methodが私の頭に浮かんだ最初のことでした。しかし、postDelayed()アクションはアクティビティが終了したときにキャンセルされ、Runnablename__が削除されます。

Runnablename__を削除するには、anonymousと宣言してはいけません。また、Handlername__と一緒にmemberとして宣言することはできません。それからHandlername__のremoveCallbacks()メソッドを適切に呼び出すことができます。

次のサンプルはデモです。

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

貢献してくれた@NSouthに感謝します。アプリケーションが閉じられた後でもtoastメッセージが現れないようにするために、Toastname__をメンバーとして宣言することができ、mExitToastname__と言うことができ、mExitToast.cancel(); justでキャンセルできます。 super.onBackPressed();を呼び出す前に。

206
Saro Taşciyan

私は最後にそれをどのようにしたかを共有すると思ったので、私はちょうど私の活動に加えました:

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

そしてそれはちょうど私が望むとおりに動作します。アクティビティが再開されたときの状態のリセットを含みます。

29
Guillaume

プロセスフロー図: Press again to exit.

Javaコード:

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

これらすべての答えの中で最も簡単な方法があります。

onBackPressed()メソッド内に次のコードを書くだけです。

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

back_pressedオブジェクトをアクティビティのlongとして定義する必要があります。

18
Chintan Rathod

正しい答えとコメントの提案に基づいて、絶対に問題なく動作し、使用後にハンドラのコールバックを削除するデモを作成しました。

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

}

私はそれが役に立つことを願っています!

12
Mehul Joisar

スナックバーを使った私の解決策:

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

シンプルでスタイリッシュ。

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

変数を宣言するprivate boolean doubleBackToExitPressedOnce = false;

これをメインアクティビティに貼り付けてください。これで問題が解決します

10
Rakshith

アプリケーションを終了するときにRunnableを使用することはお勧めできません。最近、2回のBACKボタンクリックの間の期間を記録して比較するためのはるかに簡単な方法を見つけました。次のようなサンプルコード

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

これは、サンプルで2000ミリ秒である特定の遅延期間内に2回戻るボタンをクリックすることによってアプリケーションを終了するためのトリックを行います。

9
Max Lee

受け入れられた答えは最良のものですが、Android Design Support Libraryを使用している場合は、より良いビューにSnackBarを使用できます。 。

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

組み込みの機能ではありません。これは推奨される動作でもないと思います。 Androidアプリは終了を意図していません。

Androidアプリケーションに「終了」オプションが用意されていないのはなぜですか?

6
Caner
  1. MainActivityクラスのグローバルToast変数を宣言します。例:Toast exitToast;
  2. OnCreateビューメソッドで初期化してください。例:exitToast = Toast.makeText(getApplicationContext()、 "もう一度押して終了"、Toast.LENGTH_SHORT);
  3. 最後に以下のようにonBackPressedMethodを作成します。

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

これは正しく動作します、私はテストしました。これはずっと簡単だと思います。

6
Supto

最近、私はこの戻るボタン機能を私のアプリに実装する必要がありました。元の質問に対する回答は役に立ちましたが、私はもう2つの点を考慮に入れなければなりませんでした。

  1. ある時点で、戻るボタンが無効になっています
  2. 主な活動はバックスタックと組み合わせてフラグメントを使用することです

答えとコメントに基づいて、次のコードを作成しました。

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

上記のコードはサポートライブラリが使用されていることを前提としています。フラグメントを使用し、サポートライブラリを使用しない場合は、getSupportFragmentManager()getFragmentManager()に置き換えます。

戻るボタンがキャンセルされない場合は、最初のifを削除してください。フラグメントまたはフラグメントバックスタックを使用しない場合は、2番目のifを削除してください。

また、メソッドonBackPressedはAndroid 2.0以降でサポートされていることに注意することが重要です。詳しい説明については このページ を確認してください。バックプレス機能を古いバージョンでも機能させるには、アクティビティに次のメソッドを追加します。

@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

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

    }
}

コトリン

 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)

        }
    }
5
Praveen

System.currentTimeMillis()を使ったZefnus の答えが最も良い方法です(+1)。私がしたやり方はそれより良くありませんが、それでも上記のアイデアに追加するためにそれを投稿します。

戻るボタンが押されたときにトーストが表示されていない場合は表示されますが、トーストが表示されている場合(最後のToast.LENGTH_SHORT時間内にもう一度トーストが押された場合)は終了します。

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

これは非常に古い質問ですが、これはあなたが望むことをする最も簡単な方法です。

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

私はこれが最善の方法ではないことを知っています、しかしそれはうまくいきます!

4

これは、以前のスタックアクティビティがstackに格納されているときにも役立ちます。

Sudheeshの答えを修正しました

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

ここでは、Nタップ数のコードを一般化して書きました。コードはAndroidデバイスの携帯電話の開発者を有効にするオプションのために同様に書かれています。開発者がアプリをテストしながら、これを使って機能を有効にすることもできます。

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

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

 }

バックプレスまたはログアウトオプションでaskToExit()を呼び出します。

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

この目的のために、私は以下の機能を実装しました:

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

HomeActivityにナビゲーションドロワーとdouble backPressed()機能が含まれている場合はアプリを終了します。 (グローバル変数boolean doubleBackToExitPressedOnce = falseを初期化することを忘れないでください。)2秒後の新しいハンドラは、doubleBackPressedOnce変数をfalseに設定します。

@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

これが完全に機能するコードです。また、アプリ内でメモリリークが発生しないように、コールバックを削除することを忘れないでください。 :)

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

私は通常コメントを加えるでしょう、しかし私の評判はこれを許しません。だからここに私の2セントがあります:

Kotlinでは、コルーチンを使用して設定をfalseに遅らせることができます。

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

あなたがインポートする必要があります:

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

Sudheesh B Nairの答えのいくつかの改善点、私はすぐに2回押している間もハンドラーを待つことに気づいたので、下記のようにハンドラーをキャンセルします。私はそれがアプリの終了後に表示されないようにするためにトーストをcancledしました。

 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

この状況では、SnackbarはToastよりもquitアクションを表示するのに適したオプションです。これが機能するスナックバーを使った方法です。

@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

これは一般に認められ投票されている回答と同じですが、これはToastの代わりにSnackbarを使用したものです。

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

Navigation Drawer を持つアクティビティの場合、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();
            }
        }
    }
1
Priya Rajan

これは別の方法です...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

これを使う

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

}

イベントonBackPressedに使用

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

またはExitApp.now(this,R.string.double_back_pressed)

変更秒数のクローズのために必要な、指定ミリ秒

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

1
Webserveis

Zefnusよりもやや良い方法です 。 System.currentTimeMillis()を1回だけ呼び出して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();
    }
}
1
k8C

私の場合、私はUXをより良くするためにSnackbar#isShown()に頼ります。

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

アプリを終了するにはバックプレスでコトリンでは、使用することができます。

グローバル変数を定義します。

private var doubleBackToExitPressedOnce = false

OnBackPressedをオーバーライドします。

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

Toastの可視性を使うこともできるので、そのHandler/postDelayedウルトラソリューションは必要ありません。

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

ボタンが2回押されたときに戻る

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

トーストのベストソリューション

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

コトリンで

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

これが私の考えです。

 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

同じことを何度も実装しなければならなかった後、誰かが簡単に使えるライブラリを作る時が来ることを決心しました。そしてそれは DoubleBackPress Android library です。 READMEは例と一緒に提供されたすべてのAPI( ToastDisplay + Exit Activity のような)を説明しますが、ここでのステ​​ップの簡単な要約です。


まず始めに、アプリケーションにdependencyを追加します。

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

次に、必要な動作を提供するDoubleBackPress内にActivityオブジェクトを作成します。

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

それからFirst Back Pressに表示する必要があるToastを作成します。ここで、あなたはあなた自身のToastを作成するか、libraryで提供されるStandard Toastで行くことができます。これは後のオプションで行います。

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

さて、あなたのセカンドバックプレスが起こったときに何が起こるべきかを定義します。ここでは、アクティビティを閉じています。

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

最後に、バックプレスの動作をDoubleBackPressの動作でオーバーライドします。

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

同様の行動要件のGIFの例

0
Kaushik NP

あなたはそれをもっと簡単にすることさえできます、そして、ハンダーを使わずに、これだけをしてください=)

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

これはRxJavaを使ってそれをする方法です:

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

これはあなたが必要としていることだと思います。私たちがこのトーストを見せたいとき、 スタック内に1つのアクティビティしかない場合、ユーザーが押し戻したとき このスタックの最後のアクティビティからです。

var exitOpened=false // Declare it globaly

そしてonBackPressedメソッドでは以下のように変更します。

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

ここで、isTaskRootは、現在のアクティビティがスタックの ルートアクティビティ(最初のアクティビティ) の場合はtrueを返し、そうでない場合はfalseを返します。

公式ドキュメント はこちら で確認できます

0
Suraj Vaishnav