I am trying to trigger an unlock screen when the app goes from the background to the foreground.
All my activities are extending a base class which overrides onPause + onResume.
The problem with onPause is that this method gets called even when you launch a new intent.
What is a reliable way of determining when an app becomes active?
Regards,
Tim
Looks like onResume() will do the job for you. As for the case of extending from a base class, do not forget to call super.onResume() so your onResume will end up looking like this :
public void onResume()
{
super.onResume();
// your stuff
}
Related
This is a text I have copied and pasted from this training tutorial.
"Because the system retains your Activity instance in system memory when it is stopped, it's possible that you don't need to implement the onStop() and onRestart() (or even onStart() methods at all. For most activities that are relatively simple, the activity will stop and restart just fine and you might only need to use onPause() to pause ongoing actions and disconnect from system resources."
I don't understand it. Because to the best of my knowledge, an activity is only stopped by calling onStop() and is only started by calling onStart(). How can an activity start at all without an onStart method.
Do you people understand what they mean in this paragraph?
I think they are confusing you with the word "stop" which appears to have multiple meanings in the paragraph.
I would rephrase it as
Because the system retains your Activity instance in system memory
when it is not in the foreground, it's possible that you don't need
to implement the onStop() and onRestart() (or even onStart() methods
at all. For most activities that are relatively simple, the activity
will suspend and restart just fine and you might only need to use
onPause() to pause ongoing actions and disconnect from system
resources.
The point being is that the App can appear to be stopped, when in actual fact, the system has simply paused it and hidden it from the screen. When the user launches it again, the App doesn't need to start (because it technically hasn't stopped), so it is simply resumed.
When you make an Activity and extend the base class Activity, there is already code in the onStop(), onStart(), and onRestart() methods in the base class.
Your activity simply extends these methods, meaning that you could add more code to them by Overriding them.
So, even though Activities are only started and stopped through those methods, you do not have to explicitly override them in your application. In most cases you won't even have to worry about them: They will be called by the base class from which you are extending.
Please make sure, An Activity starts from onCreate method , then onStart is called by system. If you override onStart method then your overridden method will be also called after onCreate method. If you don't override , then default version of onStart is called.
onStop is called after onPause.
Please check this link , and take a look at Activity life cycle . Your concept will be clear.
Difference between onCreate() and onStart()?
you can use an Activity just fine without - if you need to do something special in onPause() you can override the method:
#Override
public void onPause(){
super.onPause();
// Your magic here!
}
Same goes for onStart(), onStop() etc. You don't need to override the methods but you can if you need to do something specific.
I.e I would like to know when user interact with my application and when not.
I have tried do it using ActivityManager.getRecentTasks(). I have checked root activity at a top task to detect interact user with my application or not.
I have forced to check it in separated thread each second or two.
This way is bad for me. There is another way to detect when any activity of my app are opening or closed?
Have a look at the lifecycle of an Activity.
There are callback methods (onStart, onResume, onPause, onDestroy, ...) that are invoked by the system whenever your activity is created, becomes active or inactive etc.
You might create your own application class (just inherit from android.app.Application) and do your tracking there. The application will be around as long as your app is running.
For example you could put a flag or a counter there and set it from the activities' callbacks. A simple example for that could be:
public void onResume() {
super.onResume();
((MyApplication)getApplication()).active = true;
}
public void onDestroy() {
super.onDestroy();
((MyApplication)getApplication()).destroyed += 1;
}
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.
// 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
}
}
We eneded up going for something based on solution here by #peceps: Run code when Android app is closed/sent to background.
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.
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.
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.
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.
I don't know if its going to help you out but I will try in this manner
Create a base Activity and override its onStop() method to logout from server
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
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.
Is there any way to get different event for application in background and particular activity in background?
In other words when any activity goes to background the onPause() method called, is there any to find that whole application goes to background?
Is there any settings for Manifest file to close the application when its goes to background.
Thanks,
AndroidIT
To identify if the application is in background:
There is a much more simpler approach:
On a BaseActivity that all Activities extend:
protected static boolean isVisible = false;
#Override
public void onResume()
{
super.onResume();
setVisible(true);
}
#Override
public void onPause()
{
super.onPause();
setVisible(false);
}
Whenever you need to check if any of your application activities is in foreground just check isVisible();
To understand this approach check this answer of side-by-side activity lifecycle: Activity side-by-side lifecycle
If you want to kill your application when it goes to background you have several options:
Something like this: Remove or close your own Activity window from a Status Bar Notification Intent modified for what you want.
Explore: android:finishOnTaskLaunch and android:excludeFromRecents and how you can make logic to make this effect (have done it already)
I would assume that all your activities are launched by one of the other activities in your app. If that is the case perhaps your activities could set flag indicating it is launching an activity. Then when onpause() is called this flag will determine if the app is being move to the background or simply launching the next activity.
save the state of each activity in shared preferences. each activity will need its own field in the preference file. each time you onResume or onPause, update the correct preference.
or: every time you onResume or onPause send a service a notification via intent that X activity has paused/resumed. the service will keep track of application state this way
I have an issue. For analytic purposes I need to track when the APP (not activity) is resumed. The problem I have now is that if I put the tracker on the OnResume event of an activity, it will get fired every time the user goes back and forth on different activities.
How can I avoid that? How can I track the real "Application Resume," (when user actually exits the app and come back) and not the activity resume?
Any ideas is greatly appreciated. Thanks.
I encountered the same problem and solved it by creating base activity :
public class mActivity extends Activity{
public static final String TAG = "mActivity";
public static int activities_num = 0;
#Override
protected void onStop() {
super.onStop();
activities_num--;
if(activities_num == 0){
Log.e(TAG,"user not longer in the application");
}
}
#Override
protected void onStart() {
super.onStart();
activities_num++;
}
}
all the other activities in my app inherited mActivity. When an activity is no longer visible than onStop is called. when activities_num == 0 than all activities are not visible (meaning the the user close the app or it passed to the background). When the user start the application (or restarting it from the background) onStart will be called (onStart is called when the activity is visible) and activities_num > 0. hopes it helps...
Use the Application object of your app (see http://developer.android.com/reference/android/app/Application.html). If you create a custom Application class and configure it in your AndroidManifest.xml file you can do something like this:
Start tracking in the onCreate() of the Application object.
Instrument all your Activities so their onPause() and onResume() methods check with the Application object and see if they are the first Activity to run, or if they are continuing a previously running instance of the app.
Stop tracking in the onDestroy() of the Application object.
To a certain degree most of the analytics packages (Flurry and their ilk) do something similar to this. You'll need to do a little state machine work to get this to work right, but it shouldn't be too complicated.
Instead of OnResume(), hook into the OnCreate() event of your main activity.