IT이야기

활동을 종료하려면 뒤로 단추를 두 번 누르십시오.

cyworld 2022. 4. 24. 09:42
반응형

활동을 종료하려면 뒤로 단추를 두 번 누르십시오.

최근 많은 Android 앱과 게임에서 이런 패턴을 발견했는데, 뒤로 버튼을 클릭하여 애플리케이션을 "종료"할 때Toast"끝나려면 [뒤로]를 다시 클릭하십시오"와 유사한 메시지가 나타난다.

점점 더 자주 보게 되므로, 활동에서 어떻게든 접근할 수 있는 기능이 내장되어 있는가?많은 수업의 소스 코드를 살펴봤지만, 그것에 대해 아무것도 찾을 수가 없는 것 같아.

물론 같은 기능성을 꽤 쉽게 얻을 수 있는 몇 가지 방법(사용자가 이미 한 번 클릭했는지를 나타내는 활동에 부울(Boolean)을 유지하는 것이 가장 쉬운 방법일 것이다...)을 생각할 수 있지만, 이미 여기에 무엇인가가 있는 것이 아닌가 하는 생각이 들었다.

편집: @LAS_VEGAS에서 언급했듯이, 나는 전통적인 의미의 "퇴장"을 의미하지 않았다. (즉, 종료됨) "응용프로그램 시작 활동이 시작되기 전에 열려 있던 모든 것으로 돌아가라"는 뜻이었다.

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(Looper.getMainLooper()).postDelayed(new Runnable() {
        
        @Override
        public void run() {
            doubleBackToExitPressedOnce=false;                       
        }
    }, 2000);
} 

Kotlin 활동에서:

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(Looper.getMainLooper()).postDelayed(Runnable { doubleBackToExitPressedOnce = false }, 2000)
    }

이 핸들러는 2초 후에 변수를 리셋하는 데 도움이 될 것 같아.

수데쉬 B 네어스는 이 질문에 대해 좋은 답을 가지고 있으며, 나는 이 질문에 대해 다음과 같은 더 나은 대안을 가져야 한다고 생각한다.

지나간 시간을 측정하고 그 시간을 확인하는 것이 무슨 문제인가.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();
}

승인된 답변 비평에 다시 응답; a를 사용하여 마지막으로 눌렀는지 표시TIME_INTERVAL(예: 2000)밀리초 및 설정 - 재설정 수행HandlerpostDelayed()방법은 내 마음속에 가장 먼저 떠오르는 것이었다.하지만 더postDelayed()때해야 .Runnable.

제거하기 위해Runnable, 익명으로 선언되어서는 안 되며, 회원과 함께 선언되어야 한다.Handler뿐만 아니라.그러면removeCallbacks()의 방법.Handler적절하게 불릴 수 있다.

다음 샘플은 시연이다.

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회원으로 선언할 수 있다 - 라고 말한다.mExitToast- 다음 절차를 통해 취소할 수 있음mExitToast.cancel();방금 전에super.onBackPressed();전화를 걸다

결국 내가 어떻게 했는지를 공유할 거라고 생각했을 뿐인데, 나는 단지 내 활동에서 다음과 같이 덧붙였다.

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

그리고 그것은 내가 원하는 대로 정확히 작동한다.활동이 재개될 때마다 상태 재설정 포함.

이 모든 대답들 중에는 아주 간단한 방법이 있다.

내부에 다음 코드를 작성하십시오.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활동 중인

프로세스 흐름도: 종료하려면 다시 누르십시오.

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

토스트 대신 스낵바를 사용할 수 있어 앱 폐쇄 여부를 가릴 수 있다.다음 예를 들어 보십시오.

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

코멘트의 정답과 제안을 바탕으로, 나는 절대적으로 잘 작동하고 사용 후 핸들러 콜백을 제거하는 데모를 만들었다.

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

}

도움이 되었으면 좋겠다!!

 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;

기본 활동에 붙여넣으면 문제가 해결됨

어플리케이션을 종료할 때 Runnable을 사용하는 것은 좋은 생각이 아니다, 나는 최근에 두 번의 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밀리초의 일정 지연 기간 내에 더블 백 버튼 클릭으로 응용 프로그램을 종료하는 트릭을 할 것이다.

Accepted answer는 Best one이지만, 만약 당신이 사용하고 있다면 당신은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 응용프로그램이 "종료" 옵션을 제공하는 이유는?

System.currentTimeMillis()를 사용한 제프누스의 대답이 가장 좋다(+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();
   }
}
  1. MainActivity Class에 대해 전역 토스트 변수를 선언하십시오. 예:토스트 출구토스트;
  2. onCreate view 메서드에서 초기화하십시오.예: exitToast = Both.makeText(getApplicationContext()), "다시 눌러 종료", Both길이_짧은 길이);
  3. 마지막으로 다음과 같이 OnBackPressedMethod를 생성하십시오.

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

이것은 정확하게 작동한다, 나는 시험해 보았다.이게 훨씬 더 간단하다고 생각해

최근에, 나는 이 뒤로 버튼 기능을 내 앱에 구현해야 했다.원문 답은 유용했지만 두 가지 점을 더 고려해야 했다.

  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, 뒤로 단추가 취소되지 않는 경우.두 번째 제거if, 조각 또는 조각 뒷면 스택을 사용하지 않는 경우

또한, 그 방법을 아는 것이 중요하다.onBackPressedAndroid 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);
}

이게 아주 오래된 질문인 건 알지만, 이게 네가 원하는 걸 할 수 있는 가장 쉬운 방법이야.

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

이게 최선의 방법이 아닌 건 알지만,잘 작동해!

자바에서

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)

        }
    }

나는 보통 코멘트를 덧붙이곤 하는데, 내 평판으로는 이것을 허락하지 않는다.자, 여기 내 두 가지 생각이 있다.

Kotlin에서는 Coroutine을 사용하여 설정을 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

이를 위해 나는 다음과 같은 기능을 구현했다.

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

제프누스보다 조금 더 좋은 방법.System.currentTimeMillis()를 한 번만 호출하고 생략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();
    }
}

이것은 또한 이전에 스택 활동을 스택에 저장한 경우에도 도움이 된다.

수데쉬의 대답을 수정했다.

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

여기 전체 작업 코드가 있다.그리고 앱에서 메모리 누수가 발생하지 않도록 콜백을 제거하는 것도 잊지 마십시오.:)

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

탐색 드로어가 있는 활동의 경우 OnBackCompressed()에 다음 코드 사용

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

여기, 나는 N 탭 수에 대한 코드를 일반화했다.이 코드는 안드로이드 기기 전화의 개발자 사용 옵션에도 비슷하게 쓰여 있다.개발자가 앱을 테스트하는 동안 기능을 활성화하는 데에도 이 기능을 사용할 수 있다.

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

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

 }

백프레스 또는 로그아웃 옵션으로 문의하기()

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

나는 이것을 사용한다.

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)

HomeActivity에 내비게이션 드로어가 포함되어 있고 double backPressed() 앱을 종료하기 위한 funion. (글로벌 변수 boolean DoubleBackToExitPressedOnce = false;) 2초 후에 새로운 핸들러로 DoubleBackBackPressedOnce 변수를 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);
        }
    }
}
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);
}

Sudheesh B Nair의 답변에 대한 일부 개선 사항, 나는 그것이 즉시 두 번 뒤로 누르는 동안에도 핸들러를 기다릴 것이라는 것을 알아차렸으므로 아래와 같이 핸들러를 취소한다.나는 앱 종료 후 토스트가 표시되지 않도록 토스트도 캔버스로 만들었다.

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

이것은 받아들여지고 가장 많이 투표된 반응과 같지만 이것은 토스트 대신 스낵바를 사용했다.

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

내 경우, 나는 의지해 왔다.Snackbar#isShown()더 좋게UX.

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

참조URL: https://stackoverflow.com/questions/8430805/clicking-the-back-button-twice-to-exit-an-activity

반응형