覆盖后退按钮以充当主页按钮

发布于 2024-08-16 17:44:35 字数 938 浏览 10 评论 0原文

按下后退按钮后,我希望我的应用程序进入停止状态,而不是销毁状态。

在 Android docs 中,它指出:

...并非所有活动都有按下 BACK 时被销毁的行为。当用户开始在音乐应用程序中播放音乐然后按“返回”时,应用程序将覆盖正常的返回行为,防止播放器 Activity 被破坏,并继续播放音乐,即使其 Activity 不再可见

我该如何做在我自己的应用程序中复制此功能?

我认为必须存在三种可能性...

  1. 捕获后退按钮按下(如下所示),然后调用主页按钮调用的任何方法。

    <前><代码>@Override 公共布尔onKeyDown(int keyCode,KeyEvent事件){ if ((keyCode == KeyEvent.KEYCODE_BACK)) { Log.d(this.getClass().getName(), "后退按钮按下"); } 返回 super.onKeyDown(keyCode, 事件); }
  2. 捕获后退按钮按下操作,然后欺骗主页按钮按下操作。

  3. 捕获后退按钮按下,然后启动主屏幕的 Activity,有效地将我的应用程序的 Activity 置于停止状态。

    捕获后退按钮按下,然后启动主屏幕的 Activity,有效

编辑: 我了解服务,并且正在与此问题相关的应用程序中使用一项服务。这个问题具体是关于在按下后退按钮时将 Activity 置于停止状态而不是销毁状态。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

黯然#的苍凉 2024-08-23 17:44:35

大多数时候,您需要创建一个 Service 来在后台执行某些操作,您可见的 Activity 只需控制此 Service。 (我确信音乐播放器的工作方式相同,因此文档中的示例似乎有点误导。)如果是这种情况,那么您的 Activity 可以 finish像往常一样,Service 仍将运行。

一种更简单的方法是捕获 Back 按钮按下并调用 moveTaskToBack(true) 如下:

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

我认为首选选项应该是 Activity 正常完成并能够重新创建自身,例如,如果需要,从 Service 读取当前状态。但有时可以使用 moveTaskToBack 作为快速替代方案。

注意:正如 Dave 所指出的,Android 2.0 引入了新的 onBackPressed 方法,并且 这些关于如何处理“后退”按钮的建议

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.

萝莉病 2024-08-23 17:44:35

使用以下代码:

public void onBackPressed() {    
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    startActivity(intent);
}

Use the following code:

public void onBackPressed() {    
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    startActivity(intent);
}
疯到世界奔溃 2024-08-23 17:44:35

如果您想抓住后退按钮,请查看 Android 开发者博客上的这篇文章。它涵盖了在 Android 2.0 中执行此操作的更简单方法以及在 1.x 和 2.0 上运行的应用程序执行此操作的最佳方法。

但是,如果您的活动已停止,它仍然可能被终止,具体取决于设备上的内存可用性。如果您希望进程在没有 UI 的情况下运行,您应该创建一个 Service文档对服务做了以下说明:

服务没有可视化用户界面,而是无限期地在后台运行。例如,服务可能会在用户处理其他事务时播放背景音乐,或者可能会通过网络获取数据或计算某些内容并将结果提供给需要它的活动。

这些似乎适合您的要求。

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.

淡紫姑娘! 2024-08-23 17:44:35

尝试覆盖 android.app.Activity 类中定义的 void onBackPressed()

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

2024-08-23 17:44:35

如果它对其他人有帮助,我有一个具有 2 个布局的活动,我打开和关闭这些布局以提高可见性,尝试模拟一种 page1 > >第2页结构。如果他们在第 2 页上并按下后退按钮,我希望他们返回到第 1 页,如果他们按下第 1 页上的后退按钮,它应该仍然可以正常工作。它非常基本,但它有效

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

}

希望它能帮助别人,
干杯

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

猫瑾少女 2024-08-23 17:44:35

工作示例..

确保不要调用 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);
}

这样你的后退按钮就像主页按钮一样。它不会完成您的活动,而是将其带到后台

第二种方法是在 onBackPressed 中调用 moveTaskToBack(true); 并确保删除 super.onBackPressed< /代码>

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

你的他你的她 2024-08-23 17:44:35

更好的是,OnPause()怎么样:

当活动进入后台但尚未被终止时,作为活动生命周期的一部分调用。与 onResume() 相对应。

当 Activity B 在 Activity A 之前启动时,将在 A 上调用此回调。直到 A 的 onPause() 返回后才会创建 B,因此请务必在此处输入代码,不要在此处执行任何冗长的操作。

此回调主要用于保存活动正在编辑的任何持久状态,并确保如果没有足够的资源来启动新活动而不先杀死该活动,则不会丢失任何内容。

这也是执行诸如停止动画和其他消耗大量 CPU 的操作的好地方,以便尽快切换到下一个活动,或者关闭独占访问的资源(例如相机)。

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.

调妓 2024-08-23 17:44:35

android 2.0之后重写onBackPressed()。
例如

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

Override onBackPressed() after android 2.0.
Such as

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}
雪落纷纷 2024-08-23 17:44:35

我已经使用 @Mirko N. answser 使用新的自定义 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);
    }

}

然后从您的活动中设置数据

 searchEditView.setViews(cancelBtn, titleRelativeLayout);

谢谢。

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.

-残月青衣踏尘吟 2024-08-23 17:44:35

我已经尝试了上述所有解决方案,但没有一个对我有用。当尝试以调用 onCreate 的方式返回 MainActivity 时,以下代码对我有帮助:

Intent.FLAG_ACTIVITY_CLEAR_TOP 是关键。

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

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);
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文