android: Timer for Quiz app - android

I'm involved in developing a Quiz app for android. Each collection of questions should be answered within a specified period of time. This period of time can be measured using an android CountDownTimer.
However, CountDownTimer pauses when the app is no longer in focus.
What should I do if I want to timer to continue running, even if the app is closed? (If the app is reopened and the timer has expired, the app should display a suitable message).

Use the lifecycle of your Activity
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Override OnPause() method (called when activity loose focus)
stop the timer
store the current time
Override OnResume() method (called when activity returns in foreground)
compute the elapsed delay
if the timer has expired : display message
else restart the countdown timer with remaining seconds

Just listing down possible ways it could be implemented (best one first):
user2553764' s answer of just saving & calculating timer value based on system. (Best suited, it is simple & requires no background services or threads).
Using handler, see How to set a timer in android. (Official documentation suggests it use for timed operations, though seem overkill for your use case).
Using a Service (bindservice), Implementing a Count down timer using Service in the background. (But services can go out of memory, in that case might have to use it with 1st approach).
AlarmManager, dunno if it should be below binded service but it can be used none the less.
How to run a method every X seconds, suggests use AlarmManager for >10min intervals else Handlers. (Also mentioned in android documentation as you stated above).

You want to create an Alarm using AlarmManager. They run regardless of what activity is on screen, and even runs when the phone is asleep.

Related

Android: Timer keep timer active when app in background - or AlarmManager?

i use a timer in my app to start an async task (reading email) and put some status to the GUI - that works fine, as long as the app is not in background - then the timer seem to stop. Maybe it's normal.
Then i used the search function and read about the AlarmManager - but i want the timer only to run when my app is started.
How can i make sure the timer fires/works, no matter if the app/activity is in foreground / what would you recommend?
If I undestand well, you want a timer which runs only when the app is started, no matter whether it is in foreground or not. I see two options :
Set a timer in your activity : it can still live when activity is in background (onPaused or onStopped) but it can not interact with the GUI. So, you could store data in some way, and use it when activity is resumed.
Other option is to use Android services, that can continue to live with your application and execute tasks even in the background. As previously, you can retrieve data from them when the activity is back.
You should read the official documentation
Indeed, alarm manager is designed for planning tasks even if your application is stopped.

Android - Battery impact for simple background thread that periodically wakes up

I'm trying to implement a timeout mechanism for a user's login session in my app
ie. If user has not interacted with my app for say 10 mins then when he uses the app next (regardless of whether the app was previously in the background or currently in the foreground) he should be taken to the login screen.
My current implementation uses:
- a singleton instance of a Java Thread (call it 'TimeoutThread') from my 'BaseActivity' (all my activities except the LoginActivity extend BaseActivity)
- so the singleton 'TimeoutThread' will be started only the first time any post-login activity starts up.
- 'TimeoutThread' will simply keep track of the 'lastUserInteractionTimeStamp' inside a while() loop with a Thread.wait()...
so it wakes up every 2 secs, checks if the (currentTime-lastUserInteractionTimeStamp) is greater than say 10 mins and if yes then it'll trigger some callback if callback object is not null (the callback is made null whenever the app goes into background, etc)
This method works fine right now.
My concern is that since this thread wakes up every few secs (Thread.wait() inside a while(true) loop) even when the app goes into the background (eg. user presses Home button), it will cause a battery drain.
I've been unable to find a good link to explain the effects of keeping such a thread.
I did find links for power optimization, scheduling recurring tasks etc (pasted below) but couldn't directly find my answer there.
https://developer.android.com/training/monitoring-device-state/index.html
Scheduling recurring task in Android
Can anyone critique this approach / suggest a better one ?

Android - use a service as a timer?

I've read and re-read the documentation but I'm still now sure if using a service (and how) is the right way to keep a timer running.
I basically want to have a countdown timer, but I want it to run uninterrupted even if the app gets closed (and show up as an ongoing notification). When a certain activity in the app gets opened (resumed, opened, launched from clicking on the notification), I want it to be able to get the current value from the timer (no more frequent than once per second). If the app got closed, I still want the timer to be able to use/launch activities or other services (or access the database) of my app.
So if I understood the Android developer docs correctly, I should use a service that is started (because when started it should be able to do its thing even in the app gets closed) and bound (so an activity can get data from it). Then I searched Stack Overflow for similar topics and some people are recommending using IntentService (but can it send data to an activity?), or Handlers or even AlarmManager.
I'm really confused and I'd prefer to be able to pick the right approach from the start (rather than finish the app and then realize my approach wastes a lot of battery or something). The problem with documentation is it answers questions it thinks I have, so I have to ask a real person.
My suggestion is:
When user starts your timer save current system timestamp.
In your UI: Every N milliseconds just read saved value and compare it to current timestamp. This give you a diff = elapsed time.
You do not need any timer/service/alarm manager. Every time user has return to your app you just do step №2 to show elapsed time.

Android Connect to Running Thread

I am creating an app that has a UIThread and a background thread. The background thread is basically being used as a timer - every second it sends a message to the UIThread to update the UI. When the user exits the app by hitting the backbutton, the thread continues to run. I want this to happen since the user may want to open another app while the timer continues to count down.
My question is when the user comes back to my app. I want to connect to that background thread that is running to display the current state of the app - how much time is left, etc. My question is how to hook back in to the thread that is still running in the background. I have tried using Thread and AsyncTask, but the same issue occurs.
Thanks for any help that you can provide.
Your thread is still turning by sheer chance - your application is in fact still running but it and the thread will be shut down when Android decides it needs the resources.
However what you want to do is well-provided for in Android - you need to implement a Service to have a process that runs in the background separately from your application. You can even have a Service start at boot and run whether or not your application is started.
This http://developer.android.com/reference/android/app/Service.html has most of what you need to know. To communicate between the Service and a foreground Activity you'll need to bind to a service interface, which is fortunately very easily done.
First thing that comes to mind is to change your timer thread to a Service and have apps interested in it bind to that service. Based on the Android documentation and suggested app design, you cannot depend on that thread to not be killed by the OS whenever it deems necessary.
http://developer.android.com/guide/topics/fundamentals/services.html
The android system provides a broadcast event every minute, it's call TIME_TICK.
You should:
Create a service. This is the recommended way to have a part of the app running in the background
Listen to the TIME_TICK event. This will consume less battery. (It won't wake the phone, though, so use an ALARM, too)
Add an alarm (to wake the phone if necessary)
Let the UI and the service interact. You need a callback via rpc (see the last callback example on the api page)
You should also ensure that the phone can sleep during the timeframe. You thus may want to compute the state as a delta between the starting point and now, instead of updating the state all the time.

Best strategy to implement this behavior in Android app?

In my Android app, I have some data that needs to be synced daily but also needs to be updated every hour when a user is inside the app.
I have already implemented a service that gets called from an alarm for the daily update. Im having a problem with developing a strategy to do the hourly sync. I could use an hourly alarm too and fire the same intent, but since your app can be killed at any time, there would be no way to cancel it (and since they use the same Intent, doing a cancel would cancel ALL alarms including my daily sync, so that's probably not good).
The other option is to use a Timer that's set when inside the app, and have that fire my Intent when inside the app. Im assuming all Timers get cancelled when an app is killed right? But my app consists of several activities and I want the timer to work across all activities, how do I do that? I dont want to duplicate code - we're already using a subclass for Activity and ListActivity.
I have some data that needs to be
synced daily but also needs to be
updated every hour when a user is
inside the app.
The solution seems easy: drop the second requirement. Few apps are used continuously for hours on end, since people tend to use their Android phones for other things (e.g., phones), so your update-hourly-if-used-all-the-time code will probably never run.
I could use an hourly alarm too and
fire the same intent, but since your
app can be killed at any time, there
would be no way to cancel it
FWIW, your app will not be killed while it is on-screen. And, while it is not on-screen, you don't want the updates going hourly.
Im assuming all Timers get cancelled
when an app is killed right?
Apps generally are not "killed". We expect you to clean up after yourself when your activities are called with onDestroy(). If you set up the Timer with a daemon thread, you will need to terminate that thread.
But my app consists of several
activities and I want the timer to
work across all activities, how do I
do that?
Bind to your service from each of your activities. If it is started by your alarm Intent, have it do normal update processing. If it is started due to a binding request, just have it make sure its hourly Timer is running. When it is called with onDestroy() (e.g., after all activities have unbound), have it stop the Timer.
You might be able to have a Timer run in a background service (which get killed less than activities) but there is still no guarantee that Android won't kill your service either. And running something like this is the background might use a lot of battery.
What about doing the hourly sync in a background thread that get's created in onResume? And just save the last time the user did the sync, and if it has been > an hour just do the sync. Because I don't think there is any reason to eagerly sync data that the user is never going to see.

Categories

Resources