5

Is there any way to tell whether an Activity is being resumed (i.e. onResume is called) from the home screen/launcher?

For example, if I have an Application with two activities, A and B.

Scenario 1: Some user action on Activity A will invoke Activity B, bringing it into the foreground - moving Activity A into the background. As Activity A moves into the background, it goes through onPause() and onStop(). The user (now on Activity B) either finishes the Activity or hits the "back" button, bringing Activity A back to the foreground, causing an onRestart(), onStart(), onResume() sequence.

Scenario 2: If the user hits the "home" button while Activity A is in the foreground and then re-invokes the Application from the launcher, it goes through the same lifecycle as in Scenario 1. I.e. User hits the "home" button. Activity goes through onPause() and onStop(). User launches the application again, causing Activity A go come back into the foreground, again going through the same onRestart(), onStart(), onResume() sequence as in Scenario 1.

As far as I can tell, the Activity has no way of knowing how it was resumed, it just knows it is being brought back into view. In fact, I have a feeling that there isn't really as much of a concept of an "Application" in Android - in the sense of something that has a single entry and exit point.

H.Y.
  • 293
  • 4
  • 6
  • Ah. Actually, I'm trying to track the number of Application launches - but so far haven't found a way to distinguish between the different onRestart() scenarios. – H.Y. Jan 25 '11 at 03:10
  • Keep in mind there are other cases where an activity will be resumed, besides just the use of the home button. Is it a new application launch when the user gets a phone call, the system kills your app, then resumes it? I think it'll be better to track interactions in your app, rather then the "launching", however that is defined. – sargas Jan 25 '11 at 03:53
  • Yah, I am aware of these other resume scenarios. Even the approach I eventually chose ("singleTask") will register an extra "launch" when ever you switch tasks - e.g. making or taking a phone call. This means I'll over-count a bit, but it seems better than under-counting by incrementing onCreate or *really* over-counting on all onResume() calls. – H.Y. Jan 25 '11 at 19:30

4 Answers4

2

You could capture the back button press on Activity B and pass an extra value to Activity A. If there is an extra value then the activity was resumed from pressing back on Activity B, if there is no extra value then the Activity was resumed from being hidden.

Phobos
  • 9,447
  • 3
  • 25
  • 30
  • I have a feeling I'll need to handle both cases (Activity B returns with a result *and* "User presses back button on Activity B). – H.Y. Jan 25 '11 at 03:17
2

in Scenario 2, your activity will get an onNewIntent call, with the launcher intent passed to it.

superfell
  • 18,780
  • 4
  • 59
  • 81
  • According to the docs, onNewIntent is only called for certain launch modes - "singleTask" and "singleTop". I've only managed to get it working for "singleTask", however, the docs don't recommend that launch mode. – H.Y. Jan 25 '11 at 17:46
  • This approach seems to work ok for me. I do have to mark the "entry point" Activity as "singleTask", tho'. Thanks! – H.Y. Jan 25 '11 at 19:27
1

Could Acitivity A use startActivityForResult() to start Activity B and use onActivityResult() to detect that Activity B finished?

Bert F
  • 85,407
  • 12
  • 106
  • 123
  • I guess onActivityResult() would occur after all the other callbacks have finished? As I commented above, I'm actually interested in counting application launches which is why I've been hooking into onStart() and onResume(). I've seen other responses suggesting onCreate() but that doesn't fire when launching from the "home" screen. I could decrement the count if something comes back from onActivityResult() but that seems kludgy - maybe unavoidable? – H.Y. Jan 25 '11 at 03:16
0

So the straightforward answer to the initial question is probably: no. Launching an activity from the home screen through an icon, or resuming it from the recents screen can not be observed from the intent it is (re)started/resumed with.

Depending on what you are trying to achieve there are some approaches though:

  1. what @superfell suggested:

Check for whether the onNewIntent-method is called on your activity to decide if it was restarted from the launcher. As a precondition you need to set your activity to singleTask/singleTop launchMode in your Manifest:

android:launchMode="singleTask"

depending on what you're trying to achieve, this might be enough! But additionally you might have to deal with what happens when the user presses the back button. Default behavior is to finish & destroy your activity. Thus a brand new copy of it would be launched when it gets selected from the recents screen. Though onNewIntent would not be called, everything would be rebuilt from scratch. If you need to prevent this you can use:

override fun onBackPressed() {
    moveTaskToBack(true)
}

finally when you navigate "back" from an activity you launched yourself onNewIntent will also not be called. If you further need to distinguish why your activity is resumed, you might want to start the 2nd activity with startActivityForResult so the onActivityResult is called when you get resumed.

  1. Launcher activity & Intent extra

A completely different approach would be to have a "launcher" activity in your manifest that directly calls your "main" activity and finishes itself. When calling your main activity you can put an intent extra that allows your main activity to distinguish if it was just launched for the first time, or not. As the extra would be present on further onResumes, make sure to overwrite it the first time you "consume" it:

override fun onResume() {
    super.onResume()
    val firstLaunch = intent.getBooleanExtra(FIRST_LAUNCH, false)
    intent.putExtra(FIRST_LAUNCH,  false)
    if (firstLaunch) {
      // do something
    }
}

and when starting from your "launcher" activity:

intent.putExtra(FIRST_LAUNCH, true)
startActivity(intent)
icyerasor
  • 4,973
  • 1
  • 43
  • 52