How to keep Android app running in the background when home/back button is pressed.

7,860 views
Skip to first unread message

Szymon Nowak

unread,
Dec 4, 2012, 7:55:09 AM12/4/12
to phon...@googlegroups.com
Hi!

When Android app is running and I press home button or back button, my app is paused and then stopped. When I click app icon again, the app is started again. Here are the logs:

D/CordovaTest(15428): onStart
D/DroidGap(15428): Resuming the App
D/DroidGap(15428): Paused the application!
D/CordovaWebView(15428): Handle the pause
D/CordovaTest(15428): onStop
D/CordovaTest(15428): onStart
D/DroidGap(15428): Resuming the App

The "funny" thing is that when my app is running in the foreground and it receives a push notification (I'm using Urban Airship for that) and I pull down the notification panel and click the notification (while my app is still running in the foreground), my app is also restarted...

When I lock/unlock my phone, it only pauses/resumes the app without restarting it, so at least that part works fine.

Is there any way to prevent Android from always stopping the app when it's moved to the background? I understand that occasionally apps may be stopped by OS when memory is getting low or something, but it happens *always* on Samsung Ace running 2.3.6 with 278 MB RAM *and* Nexus 7 running 4.2.1 with 1GB RAM... I'm using Cordova 2.2.0.

Cheers,
Szymon

Nex Otaku

unread,
Dec 6, 2012, 3:42:09 AM12/6/12
to phon...@googlegroups.com
This is not PhoneGap-related question, this is question about Android Activities.

1. You need to set flag "alwaysRetainTaskState" to "true" for main Activity in your AndroidManifest.xml. This will make activity pause when going to background, not restarted. See here http://developer.android.com/guide/topics/manifest/activity-element.html#always

2. To resume app with notification, use same parameters as for app launch:
            Intent notificationIntent = new Intent(uiContext, YourActivity.class);
            notificationIntent.setAction(Intent.ACTION_MAIN);
            notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
 


вторник, 4 декабря 2012 г., 16:55:09 UTC+4 пользователь Szymon Nowak написал:

Airblader

unread,
Dec 6, 2012, 3:50:52 AM12/6/12
to phon...@googlegroups.com
Is there any way to change this value during runtime? In my app, I mostly don't mind when it's restarted, but if a certain page is shown it'd be nice to prevent it.

Nex Otaku

unread,
Dec 6, 2012, 4:07:43 AM12/6/12
to phon...@googlegroups.com
Nice question. I dont know. You can try to write some custom logic in onPause/onResume events, but I'm mostly sure there is a better way.

четверг, 6 декабря 2012 г., 12:50:52 UTC+4 пользователь Airblader написал:

Szymon Nowak

unread,
Dec 6, 2012, 6:13:46 AM12/6/12
to phon...@googlegroups.com
Thank you so much! I naively hoped that using Cordova/PhoneGap will save me from having to know all these config settings for iOS and Android :)

On Thursday, 6 December 2012 09:42:09 UTC+1, Nex Otaku wrote:
This is not PhoneGap-related question, this is question about Android Activities.

1. You need to set flag "alwaysRetainTaskState" to "true" for main Activity in your AndroidManifest.xml. This will make activity pause when going to background, not restarted. See here http://developer.android.com/guide/topics/manifest/activity-element.html#always

It works fine if I press "home" button, but if I press "back" button the app is still restarted... 

Couldn't PhoneGap set "alwaysRetainTaskState" to true by default? I'm not 100% sure, but I think that on iOS I didn't have to change anything to resume the app after home button was pressed.
 


2. To resume app with notification, use same parameters as for app launch:
            Intent notificationIntent = new Intent(uiContext, YourActivity.class);
            notificationIntent.setAction(Intent.ACTION_MAIN);
            notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER); 

I'm using Urban Airship plugin for PhoneGap and they provide default IntentReceiver.java file. It looks like adding:

notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);

did the trick. 

Thanks again!

Airblader

unread,
Dec 6, 2012, 6:33:00 AM12/6/12
to phon...@googlegroups.com
Why should the PG default be changed because YOU need it like this? The obvious best way to go is to let PG have the defaults that Android has unless specified differently by the programmer.

The back button exits an app -- that is exactly how Android wants it to be. You can override the backbutton behavior, but you should have a very good reason to override the exit behavior. I did this in the beginning and users were upset, so I changed it back.

Szymon Nowak

unread,
Dec 6, 2012, 6:49:25 AM12/6/12
to phon...@googlegroups.com
On Thursday, 6 December 2012 12:33:00 UTC+1, Airblader wrote:
Why should the PG default be changed because YOU need it like this? The obvious best way to go is to let PG have the defaults that Android has unless specified differently by the programmer.

To make it behave similar on all supported platforms? I admit that I've used PG only with iOS and Android, but at least on these platforms this behavior is different.
 

The back button exits an app -- that is exactly how Android wants it to be. You can override the backbutton behavior, but you should have a very good reason to override the exit behavior. I did this in the beginning and users were upset, so I changed it back.

Ah, thanks! I guess I'll finally have to add support for back button in navigation views, as currently I only have iOS-like "back" button in titlebars :)

Airblader

unread,
Dec 6, 2012, 7:52:45 AM12/6/12
to phon...@googlegroups.com
I admit, right then I was only thinking about Android, but the point still stands: I don't think that it'd be a good idea if Phonegap started pushing their own defaults. If defaults are different on different systems, let the programmer handle it. The framework, in my opinion, should stick with the defaults whenever possible.

Nex Otaku

unread,
Dec 7, 2012, 6:14:43 AM12/7/12
to phon...@googlegroups.com
Write this in your main Activity class. It should work.

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
     if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
         moveTaskToBack(true);
         return true;
     }
     return super.onKeyDown(keyCode, event);
}


четверг, 6 декабря 2012 г., 15:13:46 UTC+4 пользователь Szymon Nowak написал:
Reply all
Reply to author
Forward
0 new messages