7

My app contains an initial splash screen, followed by a listview (main activity). Clicking on each row of listview opens each activity.

My requirement is that if we single press the back button from any of my inner activities (activities that are opened when we click the listview rows), it must navigate to my main listview, and then if we press once more from the listview the app must gets closed.

So, if I press the back button from my listview twice it will exit the app correctly. My main problem is that if I press the back button twice from any of my inner activities, my app is not getting closed. I need to press three times, instead of closing the app from any of my inner activities. Can anyone please help me ?

This is my code for exiting the app. I added this code in my main listview class..

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

my manifest.xml

<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>
            <action android:name="android.intent.action.MAIN" />
            <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" >
David Buck
  • 3,752
  • 35
  • 31
  • 35
Thushara prasad
  • 155
  • 1
  • 2
  • 15

13 Answers13

13

Try this way,hope this will help you to solve your problem.

Take one flag doubleBackToExitPressedOnce which is by default (false ) in you Activity and when back button pressed first time flag value changed to (ture) and again back button pressed within 2 second exit from you app if back button again not pressed within 2 second set flag value (false).

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);
} 
AskNilesh
  • 67,701
  • 16
  • 123
  • 163
Haresh Chhelana
  • 24,720
  • 5
  • 57
  • 67
  • thanks.but its not working i'm getting the same result forced to press the back button thrice to exit the app from my activities. – Thushara prasad Oct 27 '14 at 05:27
  • @Thusharaprasad,you required 3 times to press back button fro exit ? – Haresh Chhelana Oct 27 '14 at 05:30
  • no when i press twice from any of my activities it must quit.if i press twice from my listview it must quit and if i press twice from any of my activities also it must gets quit.now the problem is that if i press twice from my inner activities it will show the toast press again to exit. – Thushara prasad Oct 27 '14 at 05:41
  • so do you no need to show this toast then simply remove Toast code. – Haresh Chhelana Oct 27 '14 at 05:45
  • this code is working only for the listview(main activity)not working on all other activities(ie activities which are opened when we press the listview items).. – Thushara prasad Oct 27 '14 at 05:54
3

This is a guaranteed working solution to exit app on 2 times back press

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

Hi I know that my answer is too late but Please take tour on the following snippet to get clear solution:

@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;
            }
        }
    };
Deva
  • 2,386
  • 1
  • 16
  • 16
1

Here is the full working and simple code to do this. And also don't forget to remove the callbacks in onDestroy method so that it don't cause a memory leak in the app. :)

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);
    }
}
Saket Kumar
  • 463
  • 8
  • 22
0

Try adding Parent Activity to the new activities in manifest.
Eg:

<activity android:name="myimagine"
          android:screenOrientation="portrait"
          android:parentActivityName="com.example.previous_activity" />
Hamad
  • 5,096
  • 13
  • 37
  • 65
Sudheesh Mohan
  • 2,560
  • 3
  • 21
  • 38
0

In Adding to Haresh Chhelana... Just create one Base Activity and after that extend all other activitys from it. That code which wrote by Haresh Chhelana insert in your BaseActivity. I think it must resolve your problem

DMan
  • 258
  • 3
  • 22
  • sorry its not working the result is that if i press twice from my listview the app will gets closed till here its fine.but if i press twice from any of my other activities its is going to listview then after pressing twice from listview only the app is getting closed.why is it so??i don't want this i need if i pressed once from any other activities it must direcrt to listview then if i pressed once more then app must get exited. – Thushara prasad Oct 27 '14 at 10:12
  • I think in this case you must kill your app instead super.onBackPressed(). Look here http://stackoverflow.com/a/14958025/3864698 – DMan Oct 27 '14 at 10:44
0

When you override your onBackPressed, after second click you need to:

  • finish an app process:

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

  • finish your first activity. Here is the example: https://stackoverflow.com/a/14002030/3864698

UPD

First case:

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

Actually google does not recommend to kill processes.

Second case:

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

In your HomeActivity don't override onBackPressed and add the next in onCreate:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // initialize a lot of variables
        if (getIntent().getBooleanExtra("EXIT", false)) {
            finish();
        }
        // some code..
}
Community
  • 1
  • 1
QArea
  • 4,955
  • 1
  • 12
  • 22
  • can you please explain it in detail?? – Thushara prasad Oct 27 '14 at 11:31
  • thanks QArea.i tried this but now the problem is that if i directly go into my listview(main activity)without going going into my other activities and when i single press the back button my app is getting closed. – Thushara prasad Oct 28 '14 at 04:38
  • sorry,that first code one that u mentioned as first case in which activity i need to add this code?? – Thushara prasad Oct 29 '14 at 06:13
  • In first case we can have one HomeActivity and all others can extend from it. So, you can paste this code in HomeActivity. – QArea Oct 29 '14 at 10:05
  • k thanks.i created one activity (home activity)and added that code in that activity and i just extended all the other activities including my listview from home activity.but it didn't solve my prblm .i got the same output.app is getting closed when i press once from my listview(without going to my other activities). – Thushara prasad Oct 29 '14 at 11:27
0

Try this way,hope will help you !

    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;
}
HuynhHan
  • 365
  • 1
  • 4
  • 11
0

After having to implement many times a behavioural requirements of capturing double back press action, built a library to do just that. The DoubleBackPress Android Library provides easy handling with builtin templates for such situations.

So for something like exiting on pressing back button twice, just do :

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

And set the new behaviour as the default for back press in your Activity.

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

Example GIF of similar requirements

Kaushik NP
  • 6,733
  • 9
  • 31
  • 60
0

Easy and Simple solution use with 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()
    }
}
Karthik Kompelli
  • 2,104
  • 1
  • 19
  • 22
0
  1. Define a global variable name Counter.

int counter=0;

  1. Override onBacPressed() methos in you MainActivity.java

  2. And follow the step as below,

In java

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

    }
Deepak gupta
  • 827
  • 10
  • 10
0

Define a boolean variable name doubleBackToExitPressedOnce.

boolean doubleBackToExitPressedOnce = true;

Override onBackPressed() method in your MainActivity.java

And follow the step as below,

@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();
        }
    }
}
Ankit Lathiya
  • 199
  • 1
  • 12
0

For Jetpack Compose use:

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue

@Composable
private fun DoubleBackHandler() {
   var lastPressTime by remember { mutableStateOf(0L) }
   val context = LocalContext.current

   BackHandler(true) {
      val timeNow = System.currentTimeMillis()
      if (lastPressTime + 2000 < timeNow) {
         lastPressTime = timeNow
         Toast.makeText(context, "Press back again to exit", Toast.LENGTH_SHORT)
            .show()
      } else {
         (context as? Activity)?.finish()
      }
   }  
}
divonas
  • 992
  • 1
  • 10
  • 11