单击Android后退按钮两次退出应用程序

clicking on the android back button twice to exit the app

我以前曾问过这个问题但不幸的是我无法找到关于这个问题的更好的解决方案。现在我的应用程序包含第一个屏幕作为启动画面然后接下来是列表视图(主要活动)然后单击列表视图的每一行打开每个活动和我的要求 如果我们从我的任何内部活动(当我们点击列表视图行时开放的活动)按下一次后退按钮时,它必须导航到我的主列表视图,然后如果我们再次从列表视图中按下该应用程序必须关闭。 因此,如果我按下我的列表视图中的后退按钮两次它将正确退出应用程序。但我的主要问题是,如果我从我的任何内部活动按两次后退按钮我的应用程序没有关闭我需要按三次而不是 从我的任何内部活动关闭应用程序。任何人都可以帮助我吗?

退出应用程序的代码是我在主listview类中添加了这段代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static final int TIME_INTERVAL = 3000; // # 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();
}
}

我的manifest.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<application
    android:allowBackup="true"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">

    <meta-data android:name="com.google.android.gms.version"
       android:value="@integer/google_play_services_version"/>


    <activity
        android:name="learnersseries.mathematics.complexnumbers.Firstintro"
         android:screenOrientation="portrait"
         android:launchMode="singleTop"            
        android:label="@string/app_name">


        <intent-filter>
           
            <category android:name="android.intent.category.LAUNCHER" />

        </intent-filter>
    </activity>


    <activity android:name="Myintegralpage"
        android:screenOrientation="portrait"
                   >

        <intent-filter></intent-filter>
    </activity>
    <activity android:name="myimagine"
        android:screenOrientation="portrait"

       >
        <intent-filter></intent-filter>
    </activity>
    <activity android:name="Myintroductionpage"
        android:screenOrientation="portrait"

      >
        <intent-filter></intent-filter>
    </activity>
    <activity android:name="MainActivity"
        android:noHistory="false"
        android:screenOrientation="portrait"
       >


        <intent-filter></intent-filter>
    </activity>
    <activity android:name="Complexnumbers"
        android:screenOrientation="portrait"
         >

        <intent-filter></intent-filter>
    </activity>
    <activity android:name="Equality"
        android:screenOrientation="portrait"
         >

        <intent-filter></intent-filter>
    </activity>
    <activity android:name="Additionofcomplex"
        android:screenOrientation="portrait"
          >

        <intent-filter></intent-filter>
    </activity>
    <activity android:name="Subtraction"
        android:screenOrientation="portrait"
        >

        <intent-filter></intent-filter>
    </activity>
    <activity android:name="multiplication"
        android:screenOrientation="portrait">

        <intent-filter></intent-filter>
    </activity>
    <activity android:name="Division"
        android:screenOrientation="portrait">

        <intent-filter></intent-filter>
    </activity>
    <activity android:name="Conjugate"
        android:screenOrientation="portrait">

        <intent-filter></intent-filter>
    </activity>
    <activity android:name="Modulus"
        android:screenOrientation="portrait">

        <intent-filter></intent-filter>
    </activity>
    <activity android:name="Reciprocal"
        android:screenOrientation="portrait">

        <intent-filter></intent-filter>
    </activity>
    <activity android:name="Square"
        android:screenOrientation="portrait">


    </activity>
    <activity android:name="Representation"
        android:screenOrientation="portrait">

        <intent-filter></intent-filter>
    </activity>
    <activity android:name="Argument"
        android:screenOrientation="portrait">

试试这种方式,希望这可以帮助您解决问题。

在你的活动中取一个标志doubleBackToExitPressedOnce默认为(false),当第一次按下后退按钮时,标志值变为(ture),如果在2秒内没有再次按下后退按钮,则在2秒内再次按下后退按钮标志值(false)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private boolean backPressedToExitOnce;

@Override
public void onBackPressed() {
    if (doubleBackToExitPressedOnce) {
        super.onBackPressed();
        return;
    }

    this.doubleBackToExitPressedOnce = true;
    Toast.makeText(this,"Press again to exit", Toast.LENGTH_SHORT).show();

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

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


这是一个有保障的工作解决方案,可以在2次退出时退出应用程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int doubleBackToExitPressed = 1;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onBackPressed() {
    if (doubleBackToExitPressed == 2) {
        finishAffinity();
        System.exit(0);
    }
    else {
        doubleBackToExitPressed++;
        Toast.makeText(this,"Please press Back again to exit", Toast.LENGTH_SHORT).show();
    }

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            doubleBackToExitPressed=1;`enter code here`
        }
    }, 2000);
}


这是执行此操作的完整工作和简单代码。并且不要忘记删除onDestroy方法中的回调,以便它不会在应用程序中导致内存泄漏。 :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
private boolean backPressedOnce = false;
private Handler statusUpdateHandler = new Handler();
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);
    }
}


嗨,我知道我的答案为时已晚,但请浏览下面的代码片段以获得明确的解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Override
public void onBackPressed() {
    if(canExit)
        super.onBackPressed();
    else{
        canExit = true;
        Toast.makeText(getApplicationContext(),"Press again", Toast.LENGTH_SHORT).show();
    }
    mHandler.sendEmptyMessageDelayed(1, 2000/*time interval to next press in milli second*/);// if not pressed within 2seconds then will be setted(canExit) as false
}


public Handler mHandler = new Handler(){

        public void handleMessage(android.os.Message msg) {

            switch (msg.what) {
            case 1:
                canExit = false;
                break;
            default:
                break;
            }
        }
    };

定义一个布尔变量名称doubleBackToExitPressedOnce。

boolean doubleBackToExitPressedOnce = true;

覆盖MainActivity.java中的onBackPressed()方法

并按照以下步骤操作,

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public void onBackPressed() {
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        if (doubleBackToExitPressedOnce) {
            this.doubleBackToExitPressedOnce = false;
            Globals.showToast(this,"Please press back again to exit.");
        } else {
            finish();
        }
    }
}

  • 定义全局变量名称Counter。
  • int counter=0;

  • 在MainActivity.java中覆盖onBacPressed()方法

  • 并按照以下步骤操作,

  • 在java中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        @Override
        public void onBackPressed() {
            counter+=1;
            if (counter==2){
                super.onBackPressed();
            }else {
                Toast.makeText(this,"Press one more time to exit", Toast.LENGTH_SHORT).show();
            }

        }


    Toast简单易用的解决方案

    In Java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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()
        }
    }

    在不得不多次实现捕获双重背压动作的行为要求之后,构建了一个库就可以做到这一点。 DoubleBackPress Android Library使用内置模板轻松处理此类情况。

    因此,对于像退出按钮两次退出一样,只需执行以下操作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // set the Action to occur on DoubleBackPress
    DoubleBackPressAction doubleBackPressAction = new DoubleBackPressAction() {
        @Override
        public void actionCall() {
              // TODO : Exiting application code
              finish();
        }
    };

    // setup DoubleBackPress behaviour
    DoubleBackPress doubleBackPress = new DoubleBackPress()
            .withDoublePressDuration(3000)                  // timeout duration - msec
            .withDoubleBackPressAction(doubleBackPressAction);

    并将新行为设置为"活动"中按下的默认行为。

    1
    2
    3
    4
    @Override
    public void onBackPressed() {
        doubleBackPress.onBackPressed();
    }

    具有类似要求的示例GIF


    试试这种方式,希望对你有所帮助!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
        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) {
                    moveTaskToBack(true);
                    android.os.Process.killProcess(android.os.Process.myPid());
                    System.exit(1);
                } else {
                    Toast.makeText(getApplicationContext(),
                           "Press again to exit.", Toast.LENGTH_SHORT).show();
                    lastPressedTime = event.getEventTime();
                }
                return true;
            }
        }
        return false;
    }

    当您覆盖onBackPressed时,在第二次单击后,您需要:

    • 完成应用程序流程:

      ActivityManager am =(ActivityManager)getSystemService(Activity.ACTIVITY_SERVICE);
      am.killBackgroundProcesses(的packageName);

    • 完成你的第一项活动。以下是示例:https://stackoverflow.com/a/14002030/3864698

    UPD

    第一种情况:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    @Override
        public void onBackPressed() {
            if (doubleBackToExitPressedOnce) {
                ActivityManager manager =  (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
                List<ActivityManager.RunningAppProcessInfo> activityes = ((ActivityManager) manager).getRunningAppProcesses();
                for (int i = 0; i < activityes.size(); i++){
                    if (activityes.get(i).processName.equals(getApplicationInfo().packageName)) {
                        android.os.Process.killProcess(activityes.get(i).pid);
                    }
                }
                return;
            }
            doubleBackToExitPressedOnce = true;


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

                @Override
                public void run() {
                    doubleBackToExitPressedOnce = false;
                    myOwnBackPress();
                    }
            }, 1000);
    }

    private void myOwnBackPress() {
        if(!isFinishing()) {
            super.onBackPressed();
        }
    }

    实际上谷歌不建议杀死进程。

    第二种情况:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    //for all activity besides HomeActivity.
    @Override
        public void onBackPressed() {
            if (doubleBackToExitPressedOnce) {
                Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                intent.putExtra("EXIT", true);
                startActivity(intent);
                return;
            }
            doubleBackToExitPressedOnce = true;


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

                @Override
                public void run() {
                    doubleBackToExitPressedOnce = false;
                    myOwnBackPress();
                }
            }, 1000);
    }

    private void myOwnBackPress() {
        if(!isFinishing()) {
            super.onBackPressed();
        }
    }

    在您的HomeActivity中,不要覆盖onBackPressed并在onCreate中添加下一个:

    1
    2
    3
    4
    5
    6
    7
    8
    9
     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
           // initialize a lot of variables
            if (getIntent().getBooleanExtra("EXIT", false)) {
                finish();
            }
            // some code..
    }


    在添加到Haresh Chhelana中...只需创建一个基本活动,然后从中扩展所有其他活动。由Haresh Chhelana编写的代码插入到BaseActivity中。我认为它必须解决你的问题


    尝试将Parent Activity添加到清单中的新活动。
    例如:

    1
    2
    3
    <activity android:name="myimagine"
              android:screenOrientation="portrait"
              android:parentActivityName="com.example.previous_activity" />