Override back button to act like home button
Asked Answered
C

10

257

On pressing the back button, I'd like my application to go into the stopped state, rather than the destroyed state.

In the Android docs it states:

...not all activities have the behavior that they are destroyed when BACK is pressed. When the user starts playing music in the Music application and then presses BACK, the application overrides the normal back behavior, preventing the player activity from being destroyed, and continues playing music, even though its activity is no longer visible

How do I replicate this functionality in my own application?

I think there must be three possibilities...

  1. Capture the back button press (as below) and then call whatever method(s) the home button calls.

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
            Log.d(this.getClass().getName(), "back button pressed");
        }
        return super.onKeyDown(keyCode, event);
    }
    
  2. Capture the back button press and then spoof a home button press.

  3. Capture the back button press, then start an Activity of the home screen, effectively putting my application's Activity into the stopped state.

Edit: I know about services and am using one in the application to which this problem is related. This question is specifically about putting the Activity into the stopped state rather than the destroyed state on pressing the back button.

Clemmie answered 4/1, 2010 at 15:9 Comment(1)
see a similar answer #5914540Ashwell
T
343

Most of the time you need to create a Service to perform something in the background, and your visible Activity simply controls this Service. (I'm sure the Music player works in the same way, so the example in the docs seems a bit misleading.) If that's the case, then your Activity can finish as usual and the Service will still be running.

A simpler approach is to capture the Back button press and call moveTaskToBack(true) as follows:

// 2.0 and above
@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

// Before 2.0
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

I think the preferred option should be for an Activity to finish normally and be able to recreate itself e.g. reading the current state from a Service if needed. But moveTaskToBack can be used as a quick alternative on occasion.

NOTE: as pointed out by Dave below Android 2.0 introduced a new onBackPressed method, and these recommendations on how to handle the Back button.

Tackling answered 4/1, 2010 at 15:49 Comment(10)
moveTaskToBack() appears to work as desired. What might the downsides be to using this method? Are there cases where this might not work as expected?Clemmie
After reading its doc more carefully, I actually think it should work fine. (I initially thought it applied to the activity, but in fact it says the "task containing this activity".) But you should test it for yourself of course. :)Tackling
Thanks Mirko, the method appears to work well. It might be cool if you give more prominence to your edit at the bottom of your answer for those looking at this question later - as that was the bit I was looking for!Clemmie
Please read android-developers.blogspot.com/2009/12/… for the recommended way to handle the back key.Iridissa
@Mirko I agree that the back button should work as normal 99% of the time, but for Audio Players it makes sense to only destroy the app when audio is no longer being played. This means the activity retains state and appears as when the user left it when they return (and they will return to turn it off). The Music Player mentioned in docs will use a service for the audio, but it's perfectly feasible that they retain Activity state, for the reason I mention above, as well. I am genuinely interested in people's opinions on this...Clemmie
@Clemmie in theory your background activity could be killed by the system if it runs low on resources, so to be safe it should be able to recreate itself anyway. I had a look at the source code for the Android Music app and don't see any special back button handling.Tackling
@Clemmie Mirko is on the money here. You can't retain state by relying on an instance of an Activity class remaining active. You need to save any state you need when your activity dies, and be able to read it when it's recreated. In the case of your application, you may simply be able to ask the Service for all the state needed when the Activity starts. Once you've done this, no reason to override the back button.Nekton
if you move your application to the back and if android system killed it for recovering some memory then when you again start your app it will call your onCreate method with the bundle of previous state saved in onSaveInstanceState.Presocratic
As developer.android.com says: The default implementation takes care of KEYCODE_BACK by calling onBackPressed(), though the behavior varies based on the application compatibility mode: for ECLAIR or later applications, it will set up the dispatch to call onKeyUp(int, KeyEvent) where the action will be performed; for earlier applications, it will perform the action immediately in on-down, as those versions of the platform behaved.Defalcate
this is awsome,, works fine for me , no need of serviceAbsorb
T
49

Use the following code:

public void onBackPressed() {    
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    startActivity(intent);
}
Tetrahedron answered 27/4, 2012 at 9:49 Comment(0)
V
23

If you want to catch the Back Button have a look at this post on the Android Developer Blog. It covers the easier way to do this in Android 2.0 and the best way to do this for an application that runs on 1.x and 2.0.

However, if your Activity is Stopped it still may be killed depending on memory availability on the device. If you want a process to run with no UI you should create a Service. The documentation says the following about Services:

A service doesn't have a visual user interface, but rather runs in the background for an indefinite period of time. For example, a service might play background music as the user attends to other matters, or it might fetch data over the network or calculate something and provide the result to activities that need it.

These seems appropriate for your requirements.

Viole answered 4/1, 2010 at 15:56 Comment(0)
J
18

try to override void onBackPressed() defined in android.app.Activity class.

Johnettajohnette answered 3/6, 2011 at 12:3 Comment(1)
since android 2.0 this is the correct thing to override. developer.android.com/sdk/android-2.0.htmlBarthel
L
14

if it helps someone else, I had an activity with 2 layouts that I toggled on and off for visibilty, trying to emulate a kind of page1 > page2 structure. if they were on page 2 and pressed the back button I wanted them to go back to page 1, if they pressed the back button on page 1 it should still work as normal. Its pretty basic but it works

@Override
public void onBackPressed() {
// check if page 2 is open
    RelativeLayout page2layout = (RelativeLayout)findViewById(R.id.page2layout);
    if(page2layout.getVisibility() == View.VISIBLE){
        togglePageLayout(); // my method to toggle the views
        return;
    }else{
        super.onBackPressed(); // allows standard use of backbutton for page 1
    }

}

hope it helps someone, cheers

Lase answered 7/12, 2011 at 0:18 Comment(0)
A
10

Working example..

Make sure don't call super.onBackPressed();

@Override
public void onBackPressed() {
   Log.d("CDA", "onBackPressed Called");
   Intent setIntent = new Intent(Intent.ACTION_MAIN);
   setIntent.addCategory(Intent.CATEGORY_HOME);
   setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(setIntent);
}

In this way your Back Button act like Home button . It doesn't finishes your activity but take it to background

Second way is to call moveTaskToBack(true); in onBackPressed and be sure to remove super.onBackPressed

Ashwell answered 20/5, 2014 at 6:48 Comment(0)
T
0

Even better, how about OnPause():

Called as part of the activity lifecycle when an activity is going into the background, but has not (yet) been killed. The counterpart to onResume().

When activity B is launched in front of activity A, this callback will be invoked on A. B will not be created until A's onPause() returns, so be sure toenter code here not do anything lengthy here.

This callback is mostly used for saving any persistent state the activity is editing and making sure nothing is lost if there are not enough resources to start the new activity without first killing this one.

This is also a good place to do things like stop animations and other things that consume a noticeable amount of CPU in order to make the switch to the next activity as fast as possible, or to close resources that are exclusive access such as the camera.

Tucker answered 18/12, 2012 at 5:25 Comment(0)
S
0

Override onBackPressed() after android 2.0. Such as

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}
Saltcellar answered 25/6, 2016 at 13:58 Comment(0)
M
-1

I have use @Mirko N. answser using made the new Custom EditText

 public class EditViewCustom extends EditText {

    Button cancelBtn;
    RelativeLayout titleReleLayout;
    public EditViewCustom(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public EditViewCustom(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditViewCustom(Context context) {
        super(context);
    }

    public void setViews(Button cancelBtn,RelativeLayout titleReleLayout){
        this.cancelBtn = cancelBtn;
        this.titleReleLayout = titleReleLayout;
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            Log.d("KEYCODE_BACK","KEYCODE_BACK");
            cancelBtn.setVisibility(View.GONE);
            this.setFocusableInTouchMode(false);
            this.setFocusable(false);
            titleReleLayout.setVisibility(View.VISIBLE);

            return super.onKeyPreIme(keyCode, event);
          }

        return super.onKeyPreIme(keyCode, event);
    }

}

Then set data from your activity

 searchEditView.setViews(cancelBtn, titleRelativeLayout);

Thank you.

Mahmud answered 22/2, 2012 at 10:51 Comment(0)
L
-1

I've tried all the above solutions, but none of them worked for me. The following code helped me, when trying to return to MainActivity in a way that onCreate gets called:

Intent.FLAG_ACTIVITY_CLEAR_TOP is the key.

  @Override
  public void onBackPressed() {
      Intent intent = new Intent(this, MainActivity.class);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
      startActivity(intent);
  }
Linnette answered 2/5, 2020 at 15:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.