Can I call a method right before my app closes? - android

Here's the situation:
I want to check if the device is rooted or not every time the app comes to foreground (either because they're launching the app through App Drawer or coming back to the app via Recent Apps list). This check is done during onResume(), and it's working well.
The problem is that the intention is to check for root only once when the app comes to foreground, not when user is currently using the app. Since onResume() is called when an Activity comes to foreground, this means the check is done multiple times even when it's not needed, which comes at performance cost.
I thought of using a static variable to lock it, locking just before I perform the check to ensure the check is only called once. This is fine and dandy, but the problem is when to do the unlock?
onPause() is called before another Activity comes to focus, which
would negate the lock. I tried to use isFinishing(), but if a user
presses the back button, the activity is destroyed, which resets the
root checking lock and renders it less desirable. EDIT: Also, the Activity is not finished if the user presses Home button, which means it's also not reliable enough
onStop() and onDestroy() are not guaranteed to be called, and
they're also called if the user presses back button.
Is there a way to call a function exactly once when the app moves to background, without restricted to the constraints of onPause() above? I searched through the Activity, Application, and BroadcastReceiver documentation but couldn't find any mention about such a thing

In the end, I decided to use a combination of onUserLeaveHint(), custom startActivity() and onBackPressed() to do it, with some private static and non-static variables
I used onUserLeaveHint() to detect when user is going back to Home
or to Recent apps list.
onBackPressed() is used to tell the app that it is used for
navigation, while another onBackPressed() override is written at the
app entry point to detect when user is using back button to go back
to Home (can't believe onUserLeaveHint() doesn't account for that)
the custom startActivity() makes sure that onUserLeaveHint() is not
called when another activity is started. While onUserLeaveHint() has issues with forced interruptions (such as user receiving a call), it is deemed acceptable for now.
I did some research and found this blog but it makes use of onStop(), which is not guaranteed to run
Thanks for all the responses. I understand the concern about my security approach, but the question is about detecting when the user is leaving the app

Related

How to properly finish (reset) an activity as soon as the user leaves it

I have an Activity that I consider a critical operation (Specific communication with another computer over Bluetooth) and I want to make it so that when the user leaves the activity, it cannot be resumed to that state. With other words, if the user resumes the activity it should be recreated.
Since this activity uses Bluetooth it might start one or two activities for result (Enable-Bluetooth activity and Request-Permissions activity) and therefore, I cannot simply finish() the activity in onPause().
By leaving the Activity, I mean presses the home button, takes a phone call or presses the multitask button
I have experimented with some Activity Launch modes (like singleTask) without success.
I already call super.onCreate(null) in the Activity's onCreate() method, preventing it from recreating to a specific state after it has been destroyed, but I want to reset the activity whether onDestroy() has been called or not.
Does anyone have any suggestions on how this should be done correctly?
Edit:
The question in the Possible duplicate explains how to quit an application and it's subtasks completely (whereas just finish() would suit my needs perfectly - if I knew where to call it). This question is about finding a clean way to not resume the previous state of the Activity.
If you never want a state persist once you've left via the home button, or perhaps even when the screen turns off, the simplest thing is to work with the lifecycle events available. It's a whole lot simpler than trying to work around Androids design by doing things like forcing the close of your app.
Since everything needs to be setup each time someone returns to the app, you can move all of your setup logic out of onCreate and into onResume. Then, perform all the required cleanup (kill your BT connection, etc) in onPause. The only possible gotchas are related to things like changing screen rotation/ opening the keyboard which might trigger lifecycle events that you didn't intend. That might make your program less responsive if you have a lot of long running tasks on the UI thread in onResume.

Do i get a Android Broadcast or Event when the app comes back to focus

I want to be notified when my Android App comes back to focus or is started. The tricky part is, i don't care for the events which appear when switching Activities within the App. The Events i am interested in are:
App is started
App is reactivated on any Activity (brought back to front by the user)
I tried handling it with the onStart() and onResume() Methods, but they fire every time a Activity is loaded and call onStop even when they just switch Activities within the app
I checked the lifecycle (http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle) but even the onDestroy() is called when solely switching Activities within the App.
How can i determine if my App is reactivated or just switching Activities?
you have to override Application class for **App is started** this will call once every time when app is open.
Two possible solutions come to mind, neither of them is very clean.
1) Use a timer
Every time in your onPause() method, you schedule a timer that sets a flag after 1 Second (or something longer, depends on your exact use-case). In each onResume() you check if the flag has been set, e.g. your App has been inactive for longer than the timer interval. If the flag is set you know the user did something else between the onPause() and onResume()
2) Set a flag manually
Every time you trigger a switch between Activities in your App, you set a flag somewhere in your application. In your onResume() method, you check if the flag is set, e.g. the switch was triggered by your App. If it is not set, the user comes from outside of your App.
Both methods, however, can't discriminate any further between possible use-cases. All these cases will look the same to you:
the user presses the home button and resumes the app at any given time later
the user turns the screen off, and back on again
the user gets a phone call and then immediatly returns to your app
This might lead to undesired behaviour of your App. I don't know what exactly you want to use this mechanism for, but you have to think very hard about all the possible cases, and if you want them to trigger your behaviour, or not.

Main activity removed from stack - set uset state as offline

When the main activity is loaded I can set the logged user's state as online by updating a remote database row. If the user exits the app I must set the user state as offline.
If the app is exited using back button I have the onDestroy() method and in there I can set the user state as offline, but if I exit using Home button and I kill the app from settings onDistroy() isn't called.
Is there a way to know when the main activity is no longer on stack, so I can update the user's state?
onStop will be triggered when user clicks on back or home button. So handle your events in onStop.
public void onStop () {
//do your stuff here
super.onStop()
}
EDIT:
Also try
#Override
protected void onPause()
super.onPause();
}
Also you could have it check if the app is finishing with
if (this.isFinishing()){
//Insert your finishing code here
}
The home button doesn't call onDestroy as the activity is still on the Activity stack where as with the back button it is generally removed. When the ActivityManager decides to remove the activity from the stack, usually after a period of inactivity or when resources are required, onDestory will be called at which point your field will be reset.
I am not able to say definitively because I don't know all the information but it would seem that removing the users logged in state when you press home (in onStart as suggested by coder_For_Life22) might be bad, as if you returned to the activity the user would have to log in again, perhaps unnecessarily and the client side session management will become even more complex.
Your method of session management seems fairly questionable anyway unless you have some sort of server side session management where, for example if there was inactivity on the session the database field would be reset.
UPDATE
The only way I can think it might be possible is using the ActivityManager.getRunningTasks() or ActivityManager.getRunningAppProcesses() and checking if your app is among them. If you kill your app like you are suggesting then your app will not be among them and thus you know. It seems like a hugely complex solution if at all possible as you would need a separate background service running (which you could call getSystemService(ACTIVITY_SERVICE) on to get the ActivityManager) just so after you kill your app you still have something running which can check for this and perform the appropriate actions.
Killing your app this way neglects the activity life cycle and thus there isn't a hook in your activity where you can perform shut down calls.
It seems much more sensible to check for inactivity on the server side and reset the field this way, people don't often kill their apps like this and when they do they aren't likely to quickly hand the phone to someone else who would be able to access the information maliciously.
If the data requires such security then you should rethink your security model.

Looking for a way to see if an application is closed

Is there a good way to check if an entire application (not an activity!) is closed by the user? I want to log the time a user spends using the application, so a simple activity onPause() ,onStop() or onDestroy() is not sufficient.
There are several ways an application can be closed, either the user pressing the home button, search button or simply leaving the application. Is there a unified (eg. simple) way to see if any of these things happened?
There are several ways an application can be closed, either the user pressing the home button, search button or simply leaving the application.
Neither of these actually closes the application. The activities will continue to run unless you explicitly call finish() or the system kills them when it runs out of resources.
Why is not sufficient to use onResume() and onPause()?
will overriding finalize() to the App class (that extends Application) help for this job ?
if not , maybe a reference inside this class to another class that has this method?

Android: Detect when another Activity is launched (or your activity loses focus)

Like the title says, I need to detect when my app loses focus because another app is launched (Phone call comes in, or user hits Home etc).
Overriding Activity.OnStop does not work because that is called even when switching activities within my app.
I believe you could use:
onWindowsFocusChanged(boolean hasFocus)
from your Activity.
AFAIK Android offers no facility for this. You may be able to track this yourself (e.g., if onStop() in one of your activities is called, and onStart() in another of your activities is not called within X period of time, presumably some other app's activity is in the foreground).
With ICS upwards this may be possible.
This is taken from the android site:
To be notified when the user exits your UI, implement the
onTrimMemory() callback in your Activity classes. You should use
this method to listen for the TRIM_MEMORY_UI_HIDDEN level, which
indicates your UI is now hidden from view and you should free
resources that only your UI uses.
Notice that your app receives the onTrimMemory() callback with
TRIM_MEMORY_UI_HIDDEN only when all the UI components of your app
process become hidden from the user.
See this page for full details http://developer.android.com/training/articles/memory.html

Categories

Resources