I am developing an app with numerous Activities. I would like to create a persistent notification that (more or less) says, "AppName - Return to AppName" that will be present whenever my background services are running. Creating and disposing of the notification was no problem.
Now, the user could be on any of several screens/Activities, leave the application, then want to re-enter the app via the notification. The problem is, the notification must have an intent, which launches a predetermined Activity. I want the notification to re-enter the app in whatever Activity is at the top of the history stack.
My first attempt at an ugly workaround was to make an activity (let's call it "returnFromNotify") whose only job was to "finish" itself in it's "onCreate". The notification would open "returnFromNotify" in the scope of the applications history, which would then immediately remove itself, sending the user back to the previous history state in the application stack. This seems to work... unless the user has used "back" to completely back out of the app. Then, when they hit the notification, "returnFromNotify" loads, then finishes, sending them back out to the home screen (as there are no activities in the history stack for the app).
I considered trying to detect if there was anything in the history stack before "returnFromNotify", and if not, fire up my main Activity. I can't seem to find a way to do this, either.
Any input or suggestions for a Java/Android novice? FYI, My primary history is with script-based languages.
I usually use activity named "Launcher" that checks state of my application model and starts activities (or does other things) depending on model rules. I put Model object in my Application class. Model can use Preferences to store its state. I do it to avoid static fields in activities.
Okay, I believe that I have found a satisfactory work-around for my specific case. I've added a static integer to my "mainActivity", and each time it's "onCreate" is fired, it increments the integer. Each time it's "onDestroy" is fired, it decrements.
In my "returnFromNotify", I look at the static integer to see if it is greater than 0. If so, I assume there is an active "mainActivity", and that running "finish" inside "returnFromNotify" will return there. Otherwise, it assumes the users has "backed" out, finishes itself, then uses "startActivity" to fire up a new instance of "mainActivity".
This is not a universal solution, but for my purposes, I think it will suffice. I am still open to other answers, and if someone can punch a hole in my logic, please do so - constructive criticism is welcome. Thanks.
I like your original idea of creating a "returnFromNotify" activity better than your proposed workaround, as it is possible to detect if the ResumeActivity is at the bottom of the stack (and therefore the only activity in the stack).
Here's how you can do it:
Add your ResumeActivity to the manifest and specify the noHistory attribute:
Specifying noHistory will make sure this Activity won't stay in the stack as soon as it finishes. This way you know that only a currently running instance of the ResumeActivity will show up in the stack.
In order to check the application stack, you'll also have to ask for the GET_TASKS permission:
Now you can use ActivityManager::getRunningTasks() to determine if ResumeActivity is the only activity in the stack:
I know you asked this question over 2 years ago, but I'm providing this answer in case anyone else runs in to this particular situation (as I did). I think you were on the right track with the solution you were originally working towards.
My first approach would be to use
SharedPreferences
and store a key value pair called something likelastDisplayedActivity
. Then in each Activity'sonResume
(and possibly `onCreate') you would have a line like this:In other words, you store an application-wide variable indicating which activity was last displayed. Then you just grab this variable from SharedPreferences and launch the corresponding activity.
I guess there is no easy way to do this but instead of adding a counter in the mainActivity I would extend Application:
I would mantein the logic there and have a method like:
to be called when the notification item is clicked.