关于android:区分推“home”按钮和打开另一个Activity

Distinguish between pushing “home” button and opening another Activity

我有三个活动:
- SplashActivity
- 主要活动
- PlayerActivity

当然应用程序以SplashActivity开头,然后启动MainActivity并关闭。
MainActivity在某个时刻启动了PlayerActivity并进入了Backstack。 (MainActivity还活着,但是在onStop上)
然后我需要打开MainActivity并将PlayerActivity设置为后台(PlayerActivity是活着的但是在onStop上)。
然后我需要再次打开PlayerActivity并将MainActivity设置为background。

因此,当app将一个切换到另一个并返回时,PlayerActivity和MainActivity经常在没有onDestroy的情况下获得onPause()和onStop()。

每次当用户按下"home"按钮时,我需要完成所有活动并启动SplashActivity应用程序,但主页按钮与活动之间的切换(onPause()和onStop())相同。所以我无法发现杀死活动的不同之处。

请帮忙。

编辑:
不幸的是,onUserLeaveHint没有帮助,它是一样的。
如果User推送HOME,则调用:

onUserInteraction,
onUserLeaveHint,
在onPause,
的onStop

此活动返回上一个活动(主),没有任何用户操作。

public class PlayerActivity扩展Activity {

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_next);

    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            startActivity(new Intent(PlayerActivity.this, MyActivity.class));
        }
    }, 5000);
}

}

但仍然有相同的:

onUserInteraction,
onUserLeaveHint,
在onPause,
的onStop


据我所知,没有办法覆盖主页按钮或听主页按钮事件。

但是,您的目标是让应用程序知道并在发生以下情况时采取措施:

  • 您的所有活动都没有显示 - >您的某个活动正在显示。

发生这种情况时,您需要显示启动对话框。

您可以跟踪用户何时在您的应用程序中,并检查用户是否从您的应用程序导航到您的活动。

更新:您可以使用ActivityLifecycleCallbacks对象来了解何时调用任何活动的生命周期回调,而不是像下面的示例所示修改所有活动。你可以拿我的例子并修改它。我相信在super.onStart()调用之后调用ActivityLifecycleCallbacks.onActivityStarted(),因此在调用Activity.onStart()中的super.onStart()之前,必须检查cameFromMyApplication()。这不容易出错,需要的代码更少。

Modified How to check if activity is in foreground or in visible background? to fit this question

Example
Implement custom Application class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MyApplication extends Application {

  public static boolean cameFromMyApplication() {
    return count != 0;
  }  

  public static void activityStarted() {
    count++;
  }

  public static void activityStopped() {
    count--;
  }

  private static int count;
}

Register your application class in AndroidManifest.xml:

1
2
3
4
<application
    android:name="your.app.package.MyApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name">

Add onStart and onStop to every Activity in the project (you may
create a common ancestor for your Activities if you'd like to):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
protected void onStart() {
  super.onStart();
  //Do not include this check in the splash screen Activity
  if(!MyApplication.cameFromMyApplication()) {
    //User arrived from outside the application
    //Application specific code (clear Activity backstack & show splash screen in your case)
  }
  MyApplication.activityStarted();
}

@Override
protected void onStop() {
  super.onStop();
  MyApplication.activityStopped();
}


你可以这样检查:

1
2
3
4
5
6
7
8
9
10
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
    // check if home was pressed
    if (tasks.get(0).topActivity.getPackageName().equals("com.android.launcher")) {
        // HOME button pressed
    } else {
        // RECENT APPS pressed (you can listen for the key event before)
        // activity with FLAG_ACTIVITY_NEW_TASK started
        // etc.
    }


您可以使用可覆盖的onUserLeavesHint()功能捕获"主页按钮单击",这可能足以满足您的需要。

1
2
3
4
5
@Override
public void onUserLeaveHint() {
    super.onUserLeaveHint();
    // Do your thing
}

来自http://developer.android.com/reference/android/app/Activity.html#onUserLeaveHint()的文档

protected void onUserLeaveHint ()

Called as part of the activity lifecycle when an activity is about to
go into the background as the result of user choice. For example, when
the user presses the Home key, onUserLeaveHint() will be called, but
when an incoming phone call causes the in-call Activity to be
automatically brought to the foreground, onUserLeaveHint() will not be
called on the activity being interrupted. In cases when it is invoked,
this method is called right before the activity's onPause() callback.

This callback and onUserInteraction() are intended to help activities
manage status bar notifications intelligently; specifically, for
helping activities determine the proper time to cancel a notfication.


我正在寻找类似问题的解决方案,上面的ungalcrys提供的代码让我朝着正确的方向前进,所以这是一个更普遍的问题解决方案,对于任何需要它的人来说

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
protected void onStop() {
        super.onStop();

        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);

        // check if the app is still visible
        if (!tasks.get(0).topActivity.getPackageName().equals(getPackageName())) {
            // for some reason(HOME, BACK, RECENT APPS, etc.) the app is no longer visible
            // do your thing here
            } else {
            // app is still visible, switched to other activity
        }
    }