14

I want to detect when my application is sent to the background. There are many questions about hooking the HOME key - I understand this is possible only by registering as a launcher app.

...BUT... as always there is a client who wants certain behaviour...

We have an app with high security requirements. The client wants the app to log out of the server whenever the app goes into the background for whatever reason (phone call, HOME key, back on last activity) (* *to clarify I mean that when the front Activity on the screen is not one of my app's activities **).

So, if I can't hook the HOME key, what other options are there? Obviously just hooking onPause() won't help, because that is Activity-specific.

The "best" we have come up with is to keep an array of Activity references in our Application class. In each Activity's onResume() we add it to this array. In onPause() we remove it. Also in onPause() we enumerate through this array to find out if any of the registered activities are in the foreground. If no foreground activity is found, user gets logged out.

I am unhappy with this as a solution, and hope to find a better way.

Richard Le Mesurier
  • 29,432
  • 22
  • 140
  • 255

8 Answers8

6

// use service

// in that

@Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);

      IntentFilter filter = new IntentFilter();
     filter.addAction(Intent.ACTION_SCREEN_OFF);
     filter.addAction(Intent.ACTION_CALL);
     filter.addAction(Intent.ACTION_ANSWER);

     registerReceiver(mIntentReceiver, filter);

}

// then in BroadcastReceiver

private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if(action.equalsIgnoreCase("android.intent.category.HOME") )
            {
//logout logic
} 
else if(action.equalsIgnoreCase("android.intent.action.SCREEN_OFF") )
            {
//logout logic
}

else if(action.equalsIgnoreCase("android.intent.action.DIAL") )
            {
//logout logic
}
else if(action.equalsIgnoreCase("android.intent.action.CALL")){
/    /logout logic
}
}
Padma Kumar
  • 19,893
  • 17
  • 73
  • 130
  • I like the thinking here, but there are other ways for an activity to go into the background - e.g. another activity bringing itself to the front. – Richard Le Mesurier Jul 09 '12 at 14:37
6

We eneded up going for something based on solution here by @peceps: Run code when Android app is closed/sent to background.

Community
  • 1
  • 1
Richard Le Mesurier
  • 29,432
  • 22
  • 140
  • 255
  • 1
    I just added a new comment to this thread where I show a better method (in my opinion) using Application.ActivityLifecycleCallbacks as well as @peceps method. See my answer for the thread : http://stackoverflow.com/a/13996042/327386 – RPM Dec 21 '12 at 19:34
3

I handled it by storing a timestamp when my activity closes\pauses. When another activity starts, it reads the timestamp and if it varies by more than x seconds I perform the log out.

If you need to physically perform a logout (i.e on a remote server), set up AlarmManager when the activity pauses to logout x seconds in the future. You can cancel this Alarm if another activity starts before it fires.

Kuffs
  • 35,581
  • 10
  • 79
  • 92
1

Or you could use a Shared Object who's a singleton, and create single onPause() and onResume() that will get/set the data on that shared object. Those functions will be used in all activities' onPause and onResume.

Rotemmiz
  • 7,933
  • 3
  • 36
  • 36
1

I worked before to solve same problem but there was no way to do it as I know except your way using now. and best overriding method to catch activity's showing status is onStart(), onStop() this method catchs real visibility change and count your activitys stack count to logout.

lulumeya
  • 1,619
  • 11
  • 14
0

android:clearTaskOnLaunch might be helpful. It does not log you out when you go to background, but you can force login screen to be the first one when you just returning back.

gshcherb
  • 1
  • 2
0

This should help:

This s a method found in the Activity class

protected void onUserLeaveHint ()

    Since: API Level 3
    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.
JoxTraex
  • 13,423
  • 6
  • 32
  • 45
  • 1
    He points out that Activities methods won't do since he uses multiple activities. It doesn't really matter if you use onPause or onUserLeaveHint. The only real difference is that the second one gets fired in less cases than the first. – dtech Jan 23 '12 at 07:25
0

I don't know if its going to help you out but I will try in this manner

  1. Create a base Activity and override its onStop() method to logout from server
  2. All Activities of my app will extend above base class.

So now what happens if on any Activity goes in onStop condition it will logout from server no matter how the Activity goes into background

Note: But if you from your code stops any Activity by calling finish then also it will logout so you have to work out in that scenario

ingsaurabh
  • 15,249
  • 7
  • 52
  • 81
  • thx - I understand the lifecycle of Android activities - the problem is trying to find out a way to work around the application-lifecycle, and the Android designers' decision to not let an app hook the HOME button. The logic you mention in your note is exactly what I am trying to solve by asking the question. I am looking for an elegant way to do that. – Richard Le Mesurier Jan 23 '12 at 07:37
  • there is no problem in that create a method in your BaseActivity that sets the boolean true when you are finishing the Activity and check that boolean value in onStop of BaseActivity depending on that value logout or viceversa – ingsaurabh Jan 23 '12 at 09:55