So I have an ongoing notification that I only want to remove when the application is closed. I removed the notification on OnDestroy when I used it in an activity. Now I want to use it in a fragment, but since the onDestroy method is not always called I remove it on onStop. When I press the home button, the notification disappears. How can I do this? (I also tried onDestroyView and that doesn't work either.)
application is closed
there's no concept of closing application really on Android.
but since the onDestroy method is not always called
That's actually fine. Putting app in background is not equivalent of killing it. There may be no need from system perspective to get your code killed/garbage collected.
Also removing notifications when user puts your app in background pretty much indicates these notifications are useless from user perspective.
onDestroy method is not always called I remove it on onStop
It indicates your notifications are tightly coupled with Fragments. That's sounds bad idea. I'd rather delegate notification handling out of the Fragment and then manage its visibility (if that really makes any sense to do) in code triggered i.e. via code utilizing ActivityLifecycleCallbacks or recent Lifecycle-aware Component.
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.
I want to know when user swipe to close app in recent list, but I haven't
found any methods yet. onDestroy and onTaskRemoved are not ALWAYS called, they depend on system or device.
So, which methods will be surely called when app closed, and I can use it in all devices?
OnPause(), is the method that is called everytime your app goes in background or losses it focus. So if you want your working to be done after the application losses it's focus use this method. Otherwise take a look at This answer and activity life cycle for more info.And as described in the answer above use Logs to identify which methods are ran in every device and then use them.
https://developer.android.com/guide/components/activities/activity-lifecycle.html
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.
In iOS when an Application goes to background or when it becomes active, event handlers in App delegate gets invoked. Is there any similar event handlers for Android's Multitasking?
Yes, see the activity LifeCycle here:
http://developer.android.com/reference/android/app/Activity.html
Not that I know of. I needed the same type of notification in my app as well to do some goes to background cleanup and comes to foreground restore type operations. What I did was subclass Activity and have that subclass call to a manager I wrote to track if the app was in foreground or background. In that subclassed activity call the manager to notify on activity "visible lifetime" events. I.E. call to say in foreground in the activites onStart and call to say in background in onStop. See this link for details of "visible lifetime" scroll down about 2 pages.
I then used my new subclassed activity as the bases for every activity in my program. So now your manager will be able to know whenever a foreground state change occurs. I then used the observer pattern in the manager to allow other objects to register to be notified of foreground state changes. This effectively mimics what we are used to coming from iOS. There may be better ways to do this but this works just fine.
I am trying to achieve the following with Android :
when the app is in background, a thread polls a server every now and then to retrieve data and notifies the user if new data is available. I am using a Service for that, fine.
when the app is in "active" use, i.e. one of its activities is visible, the polling should stop as it might interfere with other user actions.
I don't understand how to detect the transition between the "active" or "background" use of the app. The onResume() activity methods does not seem to help, as an activity can be hidden or visible during "active" use anyway. My understanding is that the app itself doesn't make the difference between the 2 states.
Can it be related when the HOME button is pressed ? Is there another way to do the distinction ?
I am thinking of an equivalent of iPhone's app delegate method applicationDidEnterBackground. Is it the right way to think with Android ? Or shall I use another approach ?
Thank you.
I'm going to reference the Activity Lifecycle. In between onResume and onPause your Activity is 'active', i.e., it's on the screen and the user can interact with it. If your activity's onPause method is called then you should assume that it is no longer 'active' and the user cannot interact with it anymore until onResume is called again. If you wish to track this in your service you're going to have to do this manually.
This is probably most easily achieved by calling a method in your service in Activity#onResume that increments a counter or sets a flag and in onPause reverting that change. If you have multiple activities then you're most likely going to need a counter, probably an AtomicInteger, and use it to determine when you should resume your polling.
I would probably wait for a small bit of time when the counter reaches 0, recheck it, and if it is still 0 resume polling. This would account for the gap between one activity's onPause and another's onResume.