How to find the spent time of android application used in foreground. i have used UsageStatsManager but it doesn't return the list of packages.
sample code used from this link
I think the best option is to use lifecycle callback methods of your activities. The start time is onCreate() of the first activity you show to your user. The end time may be a bit more tricky. First of all, if you have multiple activities, user can exit any of them, so you need to track the currently opened activity and send the end-time only if the next activity doesn't appear. The second problem is which callback method should you use? onPause() isn't guaranteed to be called, and onDestroy() won't be called until the application is cleared from recents. So probablt onStop() is the right place.
Or you can use the callbacks of your application. Just derive from Application class and use it's callbacks for your time tracking.
Related
I know that, unlike onCreate(), Application class does not have a onDestroy() method. But I wanted to know when my application is closed (or it is not visible on screen anymore). After all, whatsapp and many more similar chat applications can detect when user has left the app, and can record user's last online time. I want to achieve a similar thing. Also, when the application is destroyed, I want to detach all listeners attached to firebase databse.
I have already seen this question, but the accepted answer there is unreliable. So, what is the workaround for onDestroy() for me.
if you are talking about Application class (detecting when it is destroyed) - this is impossible, when Application gets killed developer shouldn't (and don't) have option for executing own code (as it may e.g. restart app from scratch)
but you are talking about app visibility, probably any Activity present on screen - extend Application class (and register it in manifest) and use ActivityLifecycleCallbacks with additional counting code: counter++ when any onActivityStarted and counter-- when onActivityStopped. also in onActivityStopped check if your counter==0, if yes then all your Activities are in background, so app isn't visible on screen (still it doesn't mean that its destroyed/killed)
edit: check out THIS example. or inspect supporting class ProcessLifecycleOwner (which probably is counting visible Activities for you and only calls onAppBackgrounded when all are gone)
You do not need onDestroy callback for it . You should be Doing it in onStop() of ProcessLifecycleOwner . Upon Application destroy your process will be destroys anyways in idle situation so no need to remove listeners there .
Remove the listeners in onStop and attach again in onStart . You can configure Application class with ProcessLifecycleOwner in a way so that Every Activity gets These callbacks. This is how it should works i guess if app is in background u will pop a notification of new message . Checkout ProcessLifecycleOwner.
If I, for example, need to keep some very important data which the user can edit within my app, should I need to save them every time user changes such data or is it ok if I would save it within onPause(), onStop() or onDestroy() methods?
Can somehow application end without any of those methods calling? (For instance when battery runs out)
This certainly can't be done in onDestroy().
According to the documentation:
There are situations where the system will simply kill the activity's
hosting process without calling this method (or any others) in it, so
it should not be used to do things that are intended to remain around
after the process goes away.
So yes, the application can end without calling any of the lifecycle methods.
In that scenario when the phone is shutting down, you can use the ACTION_SHUTDOWN Intent.
More info here. For all other cases onPause should do the work. Even in the link provided, there is a statement that onPause will be called if the app is in FG.
Apps will not normally need to handle this, since the foreground
activity will be paused as well.
However, if it is not so expensive operation, I would go with saving data after edit.
As per the documentation of Android activity life cycle, onPause is called when an activity is going into the background, but has not (yet) been killed.
Hence, in most Android documentation, and sample codes you will find onPause is used for saving any persistent state the activity is editing, to present a "edit in place" model to the user and making sure nothing is lost if there are not enough resources.
So in your use case, all you need to do is implement onPause for your Activity and write a code to Save the activity state (EditText content or any other ongoing user interactions). Android system will save the activity state which you can always get back in onCreate of your Activity when android launch your activity next time.
in this case please verify your phone activity via debug interface , some of phones are terminate your application this is force quit.
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.
I am porting an iOS App to Android, and am having a little difficulty with the terminally.
I want the App to sync when starting/coming to the foreground (i.e. the user selects the App) and when the App goes to the background (e.g. when going to the main screen and start using another App.)
Is there an easy way to do that in Android?
I added onResume() and onPause() to my Activities, but this will be triggered when the activity resumes or pauses, not when the App as a whole pauses (and results in a lot of sync each time the user does something).
Update:
The Sync operation is a Service which is called when the App needs to get new/updated information from the server. As such, this needs to be done when the Application is started/resumed by the suer (after inactivity for some time) and it needs to do this when the user actively stops using the Application.
when an activity goes to background,
onPause() -> onStop()
methods will be executed in sequence, if activity is partially visible, only onPause(), if activity is completely invisible by another activity, onStop() method will be executed after onPause().
onDestroy()
method will be executed if you either called finish() or when there is no enough memory in the system and system destroys it. You can't rely onDestroy() method unless you call finish() method.
It's best to use onStop() method to save your data.
nr4bt has a valid point and depending on your required functionality, a good option.
A global approach would be to start a Service when your application starts.
Make this Service responsable for your syncing operations with suitable callbacks to your active Activity.
Make this Service aware of your alive/paused/stopped Activity's. When the last one is finished -> Do your final sync and kill the Service
In Windows Phone, there is Application.LoadCompleted Event for detecting the finish of starting an application.
Note the finish means that users are able to interact with the app.
Is there similar API on Android? Any other approaches to achieve this?
after onResume() gets called it means the user can start interacting with your app. Consult this document for more information
You can override onCreate method of main Activity.
It depends what you mean by 'finished starting'. Activities, including the main activity, can be created and destroyed - and therefore onCreate() called - multiple times, for example (in the default behaviour) when the device orientation changes. onResume will be called even more often, for example every time the activity comes to the foreground. Then there's onStart(). See the Android developer docs to see when in the lifecycle each is invoked. It's true that the first time onResume() is called on the main activity will be when the app is fully started, but you won't know it's the first time without storing state somewhere outside any activity, for example on a singleton, or by subclassing the Application class, which is not something especially encouraged, as far as I can tell.