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.
Related
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
I want to send that the user is currently using the app to my server in regular interval.
User is active,
When he is on any activity of my app and the user should see it in screen.
User is Inactive,
If the user is not in any of my app's activity
If the user has minimized the app
If the user is in my app's activity only, but screen is locked
For this, I have implemented Android's ActivityLifecycleCallbacks and trying to send user is active in onActivityResumed() and inactive in onActivityPaused()
It works as expected, but there are many activities in my app, so transition between Activities also send this presence status, which is very bad for end user.
How can I control this ? How can I send only at regular intervals instead of flooding the presence ?
Generally what is the best way to do something at regular intervals in Android ? which means, the task should be done only on particular intervals even it has called any number of times.
UPDATE
How it works now and how do I need:
Making quick transitions from Launcher -> ActivityA -> ActivityB -> ActivityC
Current Behaviour:
A's onResume() triggers userActive()
A's onPause() triggers userInactive()
B's onResume() triggers userActive()
B's onPause() triggers userInactive()
C's onResume() triggers userActive()
Required Behaviour:
Since the user is actively in app after all these transitions happen, it should send userActive() only once. It can either send at first transition, (Launcher to ActivityA) or at last transition(ActivityB => ActivityC).
In simple words, the userActive() should not called if it is called within last X seconds.
Implement your LifecycleCallback as a singleton or let your Application class implement it. Let it have a counting variable.
public void onActivityResumed(){
if(activeCount == 0){
// an Activity is active ... do something
}
++activeCount;
}
public void onActivityPaused(){
--activeCount;
if(activeCount == 0){
// all Activities paused
}
}
You may want to synchronize your counting variable or use an atomic integer.
To send info on a regular interval, just let a background service check the value of activeCount periodically.
As per Android's documentation, the best way would be to implement dedicated background service which would be establishing connections on a periodic basis and send all new events in one pack.
Most of similar services are designed the same way. Backgound Service has this nice feature that it's one of the first to be killed when system is running out of memory, thus your other activities will remain intact and be running smoothly. Once resources are available again, you could configure it to pick up from where it left and send the report to your servers.
My personal rule of a thumb: if something is not directly related to handling user controls, make it as a service
--- Edit 1:
Android Documentation
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 building an android app for fetching internet data and rendering it as a list. The data is changing every minute, so I made a service and used a Timer to load the data with an interval.
My question is that:
I want to know when the app (not a particular activity) goes to the background, for example, user pressed the home button, in that case, I want to pause the service in order to save battery.
I want to know when the phone is sleeping (screen dimmed), in that case, I would like to pause the service too.
Any ideas?
Pause your service in onPause (and resume in onResume).
Unless you have a wake lock, your app will not run when the phone is sleeping.
If you're bound to a foreground app, why use a service in the first place?
To elaborate on 1: I understand you're saying "app", not "a particular activity", but your best bet is to use Activity.onPause and Activity.onResume. If anything, you can add a short delay so that nothing happens if onPause is followed immediately by onResume.
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.