I want to store user logged out time in the database(for maintaining the user analytics) when the android app forcibly closed by user. Is it possible to capture event in MainActivity?
can any one suggest the better approach to achieve this?
there is no reliable way for this event detection - this would be kind-of insecure to inform app that it's going to be killed allowing to execute some code at that moment (as in your case - database handling). user clearly wants to stop this app, when it would get a possibility to execute some code just before gets killed then it may e.g. leave some alarm for now + 10secs in AlarmManager to restart some background service. this is opposite to what user wanted
best you can do is listening when last Activity is destroyed (onDestroy call), but this may occur in multiple cases, no ony force stop app by user. use some static int and ++ when Activity is created and -- when destroyed or use Application.ActivityLifecycleCallbacks on never APIs
Related
I have written an android app that uses firebase anonymous authentication and writes to the firebase database from a foreground service. I am using onDisconnect().removeValue() to cleanup data created by my app when the websocket is closed. When a user is actively engaging with the app, the onDisconnect() call triggers as expected (meaning my security rules are OK). However, when the foreground service is left running for a long period of time (e.g. overnight, screen turns off, etc.), the onDisconnect() call is never triggered again. The app continues to function upon wakeup (communicating with firebase server, etc.) but when it comes time to close the app (following a period of idle time), it seems that the onDisconnect() call has been lost somehow.
I have read that anonymous authentication sessions are quietly refreshed by the firebase SDK every hour. Is it possible this is happening in the activity (and being killed by the OS, but keeping the foreground service alive), therefore causing the server to discard the callback to onDisconnect? If so, can this functionality be preserved within the foreground service?
Firebase has had a bug recently (not sure if it's been fixed), where when it reauthenticates every hour, it loses the onDisconnect() because it no longer has permission to alter that node. This then causes the duplicate.
Some possible solutions:
Attach a timestamp and check if the last timestamp is over an hour, and if it is, then delete it when adding the new one.
Remove authentication requirements for writing in the node to keep track of the disconnects (this would not be secure though, depends on your needs).
Here are some more alternatives, and a better explanation of the problem from a member of the Firebase team: here.
Android application processes can live indefinitely. When the user stops using an app, Android may continue to keep the process alive, in order to make it load faster if and when the user comes back. You can think of this is an optimization, and you should expect this to happen sometimes. You shouldn't try to control this behavior - let Android manage this for you.
Your connection to the database is not being closed because the app is still alive and holding on to its connection to the database. I suggest you track for yourself when the user stops using your app, and force a cleanup at an appropriate time after that, without assuming that Android will ever kill your app's process.
In my application I check to the server some user state in the onCreate() method of the main activity.
I recently notice that doing so is an issue when I run the app from Eclipse while the phone is asleep (screen off, locked). In this situation, the application waits that the screen get unlocked to call the onStart() method and pursue its way. That makes fail the data update.
Maybe I should put it inside onStart?
Can the user do the same process = start an app with locked screen? I though of Tasker but are there other way?
Edit: All the server updates communication are done off main thread, handled by managing classes and I use volley. So it's not a service and though I will put one later, I have not enough time to do it now. Except if you say it's 2 days work to learn and implement. Can a user start an application like a dev can do it ?
This things that you are doing in an Activity must surely be performed in a Service. Android Service provides you with doing background data processing/syncing.
If I make a call to an external web service and the user rotates the device, the Activity will restart (I know you can handle it yourself but this is not recommended). I know I can preserve the state using onRetainNonConfigurationInstance().
The question I have is what happens to the inflight network IO after the Activity restarts? Does it continue, is it suspended or killed?
I am rather new to Android (iOS person) so the restarting Activity is rather odd.
Some network calls we make could be restarted, but checking out for a purchase is not one of them. How do I handle this so that purchases still work correctly? Assume I would use Asynctask (though I realize there are other choices such as Executors).
For network calls that need to maintain across activity restarts (e.g. purchase), consider using a service instead of doing it inside the activity.
If your connection is defined as instance variable inside the activity it will be destroyed/killed when the activity restarts.
Another alternative, but I would not recommend, is to implement an application class and maintain your connection there so it will be persistent as long as your app process is alive.
You should not be handling requests inside activities unless they are simple enough to fire off (i.e., do not require responses). The common use case is that you are interacting with a REST interface that you want to handle across multiple activities. The basic idea is to issue requests to the service and let it mediate the connection for you. Google IO 2010 had a good lecture that you can listen to.
Implementing the functionality inside an Application class is not recommended, as you will get strange behavior when your app is killed by Android when memory is tight.
I have created an application in Android. This application should never die (even when sent to the background).
Currently, after a while the Service manager returns "No longer want..." and terminates it.
I've read that one solution whould be to create a service. However my application is way to complicated to be splitted into two functionality sets (one for the service and one for the application).
Is there any "trick" in order to keep my application running at all time?
Could I create a dummy service inside my application that might force the android to keep my application alive?
Is there any other way?
FYI: 1) It's a customized application that will not be released on the Market. 2) Handsets can't be rootted.
Thanks
You must create a Service to have a persistently running app, even after all your Activities have been sent to the background due to user pressing the Back button, answering a call, switching to another app, etc. You should review the Android Process Lifecycle which states that:
Sometimes an Activity may need to do a long-running operation that
exists independently of the activity lifecycle itself. An example may
be a camera application that allows you to upload a picture to a web
site. The upload may take a long time, and the application should
allow the user to leave the application will it is executing. To
accomplish this, your Activity should start a Service in which the
upload takes place. This allows the system to properly prioritize your
process (considering it to be more important than other non-visible
applications) for the duration of the upload, independent of whether
the original activity is paused, stopped, or finished.
I'm wondering what is the highest level I can go in-order to know when the user interacts with my application
preface: I'd like to logout of my application after X seconds of user inactivity.
so what I did is create a service with a timer, and a toggle function which resets the timer to X time.
after X time has passed, an intent is raised, and a broadcast receiver catches that intent and preforms the logout (closing the open logged in activities as well...)
as for the actual question, I need to call the "Timer Toggle" function each time the user interacts with the application.
where is the highest place in the android app that I can know when the user interacts with the phone
The only thing I found is to implement onClick and onKeyPress for each activity, is there another better way? maybe in the Application class?
I don't think there's any other way aside from sending events from the Activity itself.
You could look at overriding Activity.onUserInteraction().
But is it likely that the user will be in a single Activity of your application for "X seconds" without ever switching screens, or letting the device go into sleep?
I imagine it would be sufficient to update the timer/flag in onCreate, onPause and onResume. Plus maybe some commonly-called functions within the Activity.