How to make LAUNCHER activity be started instead of activity on top of activity stack after process is killed by OS? - android-activity

Hi I have looked for this question and can’t find it, so here goes...
My application starts with a sign in activity which logs the user in. Upon successful authentication, the initial launcher activity is replaced by a ‘content’ activity.
Everything works fine until I place the app in the background via the home button and start up some memory consuming applications.
Upon returning to my app, Android tries to recreate the activity on the top of the activity stack, however what I’d like is to have the signin activity be restarted instead.
The reason being that the user needs to be reauthenticated again due to inactivity in communicating with the server.
Is there a way of specifying this behavior in the Manifest.xml file or programmatically?
I’m aware of save/restore activity state, but in this case I want the app to restart with the signin activity, thus bypassing needless restore. (Since the user will have to be signed in again due to inactivity)
Thanks for the help!
UPDATE:The issue arises solely when my application process is killed by Android to reclaim memory to be used by other apps that are being loaded. The only aspect of my app that still exists at that point is the activity stack and its top entry is my MainActivity. This is because the activity stack is NOT inside the app process.
So Android is attempting to be nice to the user and it tries to restore the state of my MainActivity. However my ability to authenticate against my server is gone at that point because the user’s credentials have been wiped from memory together with anything that used memory.
Therefore instead of attempting to restore my MainActivity under these conditions, I’d like my app to start at the activity which is designated as the LAUNCHER activity in the Manifest.xml file. This activity implements the signin process which gets credentials from the user and sets up various singletons whih are not tied to any specific activity. NOTE: I don’t want to persist credentials or cookies for various reasons, so that is not an option.

Related

Fire Chrome Alarms from background service when using cca Google Chrome apps

Experimenting with Mobile Chrome apps API: ( https://github.com/MobileChromeApps/mobile-chrome-apps )
What I'm trying to achieve is the registering of my chrome alarms without having to crudely start the apps' main activity as this causes a bad user experience.
The challenge:
I have specified a chome.alarm which gets successfully registered when I open the app ('cca run android ' for example). These alarms are specified in a background.js file, which is declared as a background script in the manifest.json file.
I wanted these to be registered automatically on boot, therefore I implemented a background service and thought I could simply call the app to register the alarms specified in the background.js file. However, the only way I can find thus far to achieve this, is via a call to launch the apps main activity via an Intent from within the background service as explained in more detail below.
On boot, my background service simply invokes:
//Launch main activity..
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.company.appname");
startActivity(LaunchIntent);
The above launches the app into its main activity and the aforementioned chrome.alarms are registered as desired. Happy days! A massive downside to this, of course, is that no user wants the full blown main activity window to open on boot.
Please advise if there is a less clunky way to have the chrome.alarm specified in background.js registered at boot by a background thread. I do not wish to open the mainActivity of the app, yet this is currently the only way thus far I can see to get them to be registered. It is preferable not to register these alarms from within the Android SDK as I intend to stay as close to using web APIs and want to use background.js as the hook to do this keeping things in-line with chrome web apps as-well-as the android platform.
What I have done:
A cca (chrome mobile web app) app which registers a background service natively (I extend BackgroundService) as a plugin and register this to run at boot time. This is the only 'native android code' in order to load the app at boot-time.
Upon booting android, this background service then simply issues a startActivity(LaunchIntent) in order to open the app. In doing so, my chrome.alarm specified in my background.js file get registered successfully. If I don't do this, my chrome alarm specified in background.js do not get registered until I manually open the apps main activity. Therefore I use the backgroundService to open the apps main activity.
This is not at all ideal, I would simply like to somehow have my chrome.alarms registered without crudely having to launch the apps main activity window.
Is there a call which I can place in my BackgroundService to have only the chrome.alarms contained in my background.js file read and registered to fire?
Thank you for your time.
First, thanks for using Chrome Apps for Mobile! (Note: I work on the project)
Sorry that our current bootstrap is "crude" and "clunky", and we agree that it is. You can track this issue for progress on our effort to replace our current Background-scripts-embedded-in-main-Activity-webview strategy with a real background service and multiple window support. Basically you've summarized exactly our plan and existing limitations.
This work is actually scheduled for the near term, and will certainly be done before the end of the year.
As well as chrome.alarms, this feature is quite important for chrome.gcm and chrome.tcpServer (among other reasons).

Monitoring regions but location icon disappears when app is killed

I have a CLLocationManager contained in a singleton and I have added around a dozen regions to monitor. I am successfully notified of boundary crossings when the app is in the foreground/background. However, when I force quit the app, the location icon disappears and I am not getting any callbacks.
As far as I can see, this is intended functionality as of iOS7. Here is a reply I found to a similar question, in this case involving significant location change: https://devforums.apple.com/message/882691#882691:
If a user swipes up in the app switcher then the OS will not launch the app unless explicitly told to do so by the user. So no, SLC will not be launching the app, nor will silent notifications. The only thing that will launch the app at that point is the user tapping the icon. The intention here is that the user has expressed their choice of not having that app running any more for any reason, so we honor that.
In this situation, there's really nothing that you can do. The next time the user launches the app you can let them know that some of the data may be missing, although you really cannot tell whether there's missing data or not (i.e. you might have been killed by the OS in the background and the user may not have moved thereby not triggering any SLC notifications). My suggestion would be to gather the data you can within the policies of the OS and if the user has manually killed the app then respect that wish and don't do anything.
By all means, feel free to file a bug report if this change in behavior winds up causing problems for you or (especially) confusion for your users.

Prevent app from shutting down when device is rebooted

When I restart the device my app is on it won't preserve the state it had once I open up the app again, it will be as if it's the first time I open, losing the session and having to re-login, how can I make my app preserve its state even through a device reboot? Like Twitter does, for example.
I'll try a bit more formal answer based on the comments you added above. I'll start by saying that the link Tim posted is something you should familiarize yourself with.
When your app is running, it's in the Foreground state. When you "exit" an app with the Home button, you're not really quitting it; you're just pushing it to the Background state. after a few seconds in background state, the OS automatically moves the app to the Suspended state. If you come back within a few minutes, your app is still in memory, so the OS just puts it back on the screen the way it was.
However, if you leave the app alone for a while and use other apps, the OS can--at any time and without warning--purge your app from memory. This is known as the "Not Running" state. Now, when the open the app again, it has to start from scratch. Obviously, the same thing happens when the device restarts--all apps are purged from memory.
The trick, then, is to save essential information about the app state whenever it enters the background state. You can use the app delegate's didEnterBackground method, or register for the UIApplicationDidEnterBackgroundNotification and invoke a method in your active view controller (or any other class, for that matter). Either way, you should save whatever state information you can.
How do you save this information? There are several strategies. For a simple app, perhaps you can register a few setting as NSUserDefaults. Or maybe you can write out a file containing whatever data the user was working on. It's really up to you.
Then, whenever the app launches, check for the presence of that saved data (however you chose to write it out), and set up the UI accordingly. To the user, it will appear as though the app never quit, which is exactly what Apple wants them to think.

How to take action everytime user starts/stops app regardless of the activity they're on

I'm in the process of porting an app originally developed on iOS to Android. I'm trying to accomplish the following:
every time the app is started, call the start() method on a Manager class
every time the user leaves the app, call the stop() method on the same Manager class
every time the user comes back to the app (resuming from idle), call the start() method on the Manager class
The so-called Manager class handshakes with a server on the Internet and needs to do a variety of book-keeping activities every time the user the user enters and leaves the app.
Whereas iOS enables you to subclass the UIAppDelegate class and have code that runs when the app starts, ends, or resumes from idle, it seems Android doesn't have an equivalent approach. Instead, these are the options with Android:
1) Activity class: methods for every time an Activity (view) is created, stopped, or resumed
2) Application class: onStart and onDestroy for every time the app is started or killed
3) Service mechanism to create a background task that can be used to perform long-living operations in the background while the app is active or even while its not active
None of the above align real well with what I'm used to in iOS. Option 1 would require every Activity in the app's view hierarchy to have code that runs when the app starts/stops/resumes. Of the 3, I sense option 3 is more relevant. I'm just not entirely clear how I could start/stop a service in Android as the user starts/stops/resumes an app without regard to the specific activity they're on at the time.
I would appreciate input from Android developers or developers that work on both iOS and Android.
The so-called Manager class handshakes with a server on the Internet and needs to do a variety of book-keeping activities every time the user the user enters and leaves the app.
This might be a valid design pattern on iOS -- I have no idea. It is not a valid design pattern on Android. You don't "leave the app" on Android any more than you "leave the app" in a Web app. "Leave" is determined mostly as "you didn't come back in a while" in both Android and Web apps.
2) Application class: onStart and onDestroy for every time the app is started or killed
Note that the method is onTerminate(), not onDestroy(), and it actually never gets called. The Application object is created when the process is and lives until the process is terminated outright.
Its just not entirely clear how I could start/stop a service in Android as the user starts/stops/resumes an app without regard to the specific activity they're on at the time.
You might elect to use a service for doing the "handshaking" -- in fact, that's probably likely.
However, there is nothing built in for "leave the app". I would strongly encourage you to simply get rid of the concept entirely.
If not, you're welcome to rig up a service that is notified on each onPause() and onResume(), does the bookkeeping to see if there are any live activities, and if there hasn't been for X period of time, does your "leave the app" logic, then shuts down. You'd also trigger the "leave the app" logic in onDestroy(), if the service is shutting down at OS request vs. your own shutdown request. This is not 100% guaranteed to work -- users can force-stop your service and the OS can kill the process with impunity.
If you want to avoid duplicating code in all your Activities, why not have 1 subclass of Activity with the common code, and have the other Activities subclass that?
You can track activity lifetimes using a variety of mechanisms, including setting/clearing SharedPreferences in onPause/onResume, or use a singleton with reference counting.
Hope this helps,
Phil Lello

How to load the initial view every time an app launches?

I am fairly new to iphone app development. I am creating an app that has multiple views. Initially it starts with a view for authentication and then load views according to user interaction. When I build and run the app - the first time it shows the "Default.png" screen and then shows the first view where I do my authentication process (typing in userid,password and do a web service) and then after the credentials are verified it takes me to the next view. When I close the app at this state in the simulator and reopen it again, I am seeing the same state in which I closed my app. But here is what I want. When I relaunch the app I should be able to show the "DEfault.png" and screen and then show my initial authentication view. Can you please help me out on this ? Thanks
It sounds like the problem you are trying to solve is that your authenticated session may time out while the app is suspended and you need to log in again.
Although the proposed solution (setting UIApplicationExistsOnSuspend to true) would work I think you should consider a different approach.
Apple recommends that you do everything you can to make it look like the phone supports multitasking. That is why, by default, your app will suspend and resume instead of exit and relaunch. In your case, though, you may need to re-login to resume the session. I offer you a couple of alternate solutions:
Cache the credentials (ie username and password) and silently use them to resume the session when needed. If the back-end supports this.
Detect when the session has become stale and bring in a view to inform the user that the session has expired and ask them to log in again. This would also address the issue if the user keeps the app active past the timeout of the session.
Both of these approaches should improve perceived app performance and integrate better into the Apple usability guidelines.
That's because iOS 4 apps are supposed to support multitasking. You can change the app so it doesn't: In Info.plist, set UIApplicationExitsOnSuspend to true (i.e. <key> UIApplicationExitsOnSuspend</key><true/>) — make sure it's a boolean and not a string. Note that this will probably make startup slower, since the app has to be launched again.
The other way is to handle applicationDidEnterBackground: in your app delegate and do two things:
Reset your view hierarchy (you can do this on next launch, but doing it earlier might help to free more memory)
Show "Default.png" in a full-screen view — iOS takes a screenshot of your app after it's hidden which it uses to animate the app back in.