I've got a clock in my widget that I'm making and I want it to update every minute in sync with the system clock. ACTION_TIME_TICK seems like the perfect solution however much of my research says it's impossible in an AppWidget while others say there are workarounds but their very vague.
I'd prefer not to do an AlarmManager as I'd have to update very frequently to make sure that it changes minutes when the system clock changes minutes and that would drain the battery more.
Is there a workaround for ACTION_TIME_TICK or what's the best way to update every minute in sync with the system clock with minimal battery drain?
Is there a workaround for ACTION_TIME_TICK
ACTION_TIME_TICK can only be registered via registerReceiver() from something that is already running. In your case, that "something" would need to be a constantly-running Service, and that's generally an anti-pattern. Users and the OS can get rid of that service when desired.
I would find a way to lightly relax the "in sync with the system clock" requirement, then use AlarmManager. After all, Android is not a RTOS, so nothing will be "in sync with the system clock" in any guaranteed sense.
Using AlarmManager, you would specify the first alarm to be the "top" of the next minute, with a period of 60 seconds and setRepeating(). Or, you would set(), scheduled for the "top" of the next minute, then schedule the next one via set() as part of your own processing, if you think you can manually correct for drift better that way.
if you just need to display it when your app runs then just update it using asyncTask
but if you need it's value even in the background then using service would be the best idea
Related
I'm programming an update interface in my Android Things project. I can do manual update, with an user input. But I'm trying to schedule an auto-update every night at midnight. I want to use a custom UpdatePolicy with a deadline but I failed to use it.
I tried this in the onCreate method in my activity :
mUpdateManager.setPolicy(
new UpdatePolicy.Builder()
.setPolicy(POLICY_APPLY_AND_REBOOT)
.setUpdateDeadline(10, TimeUnit.SECONDS)
.build());
But there isn't any update after 10 seconds.
Maybe, I don't understand the deadline.
Do I use it wrong ?
The deadline has nothing to do with when an update check is performed. The usual schedule of update checks is
once shortly after boot
once every 5 hours (approximately) thereafter
(These times are not exact for reasons that aren't relevant to this discussion.)
The deadline reflects how long the device will let an available update sit without being applied before the device will force it to apply and reboot. The device doesn't know about an available update until it performs a check, so you could be waiting up to 5 hours for that.
The deadline is meant to operate on a longer timescale (for instance, 5 days, a week, etc). This is useful as a fallback in case there's some kind of bug with the update scheduler, or in case you allow users to postpone the update but don't want them to be able to do that forever.
To achieve what you want, you should schedule (using WorkManager, JobScheduler, etc) a task that runs at midnight each day and calls UpdateManager.performUpdateNow(UpdatePolicy.POLICY_APPLY_AND_REBOOT)
TL,DR: Update checks are very much a background thing. If you care about timing at all, use UpdateManager.performUpdateNow, but no more than once every 5 hours.
I have an Android Application that uses a Countdown Timer that lasts for around 2 days. What is the best method to avoid my Countdown Timer from being killed by the Android Application Manager even if the user enables a power saving mode or restarts their phone ? (Sorry if this is a senseless question to answer, for the reason that I am new to Android development.)
What is the best method to avoid my Countdown Timer from being killed by the Android Application Manager even if the user enables a power saving mode or restarts their phone ?
That is not possible. Moreover, it is very wasteful (tying up system RAM, spending CPU time). If you want to get control at a certain time in the future, use methods on AlarmManager (e.g., setAlarmClock()). If you want to find out how much time remains between now and that certain time in the future, find out the current time (e.g., System.currentTimeMillis()) and subtract that from the future time to calculate the difference in times. To handle a reboot, you would need to set up the AlarmManager again, by using a BroadcastReceiver set up to respond to ACTION_BOOT_COMPLETED.
I want to create a Reminder application with a similar idea like this, but this implementation only have at most one alarm/reminder at a time (ie. when an alarm starts, we can only configure another alarm after the most recently fired alarm has finished). Where do I start if I want to implement an application that can fire off multiple alarms?
My initial idea is like this:
For example my reminder application has 10 alarms for today, 20 alarms for tomorrow, etc (a certain number of alarms at a certain day). Should I just create a fixed amount of threads and process the alarms one day at a time? Or maybe I can reuse a timer and timer task but dynamically change the delay value? Please help shed some light for this.
Should I just create a fixed amount of threads and process the alarms
one day at a time?
No, just create a thread when it's needed, to be honest you can just have a clock checker within your application and a table or some data structure which holds type of alarm, time, whatever else there and create thread only when it's needed, it will play sound, wait for termination, etc. (basically user input) or just wait for it to die after it will be done with its work. You can have some kind of fixed iteration amount.
Where do I start if I want to implement an application that can fire
off multiple alarms?
Think about what kind of features you want to add, this will pretty much shape design of your application, design yourself some kind of manager of alarms, and system to create an alarm at a certain time.
Make sure you use FXML and force yourself to keep things organized, since your application can get bigger as you go on and add additional features.
Think about what data will be shared between threads since it's highly possible that you will not like to let threads/alarms overlap each other // for instance when they will have "remind in 5 minutes" //, or just terminate alarm that's about to cross into another one, if user doesn't terminate its alarm within that period and it just keeps going and another one is gonna be started, make sure that there is an entity or some higher controller class which takes care of this. If you don't wanna limit this to some minute interval maximum.
This application that you have in your mind is quite small and trivial you might be able to avoid most problems.
Keep it simple, this might be a best advice anyone can give you.
Bud it's just my personal take on this, these kind of questions will attract opinion based answers.
Ever played Candy Crush? Know how you run out of lives and have to wait 30 minutes to regenerate a new life and up to a maximum of 5? That is idea I am trying to implement in my app but I am uncertain on how to have code running even when the user closes app and/or phone.
My question is how to have a timer constantly running in the background of phone until the timer hits X minutes. Would I use the Timer class for this? Because I am familiar with that class and already have a form of it implemented in my app.
There are two pieces to your question:
To actually have a timer running so that you have an action taken after a certain period of time, use the AlarmManager. This should only be used if you are going to proactively interrupt or notify the user.
Your scenario doesn't actually need a timer, and it's more efficient not to use one unnecessarily. Instead, store a timestamp. When your app is opened again, compare the current time to the timestamp and calculate the effect. In the regenerating-lives example, you'd compare timestamps, see that 100 minutes have passed, divide by 30 minutes, and add 3 lives (maybe keeping the extra 10 minute remainder).
If you want timer to run in background you may use AlarmManager. You can set Alarm at specified intervals or you can set it in service if you want single shot alarms. Also while using AlarmManager beware that if your phone goes down then all alarms you've set will be vanished. So take care that you are saving alarm times before phone goes off. Take a look at:
http://developer.android.com/reference/android/app/AlarmManager.html
While using AlarmManager, use correct PendingIntent flags or you could lose previous alarms. If you still want more information you can raise here or have a google.
I don't think you can keep a timer running for you application even when the application is closed. Here is an idea i think about:
You need to start a timer when the life is gone and your application is running.
On your application close event, save that timer value in a persistent storage such as file
On appliction start, read the timer value from the persistent storage, and restart the timer for the remaining time
Once timer expires, generate a new life.
Hope it helps!
I found this answer that might be of great help. Hope it helps others.
There are several different approaches.
You can make use of the System's AlarmManager.
You can make your own Service.
You can make your TimerObject persist.
Check the link for the complete answer and links.
Disclaimer: My app already working without any Wake Locks for 1+ year and all is well for most devices.
I'm tracking GPS and it works like this:
AlarmReceiver starts Service every 5/10/15 minutes (as user wishes)
Service subscribes for Location updates and waits MAX 1 minute for good GPS.
Wrap up, send data to server and shut down service.
Due to bad connections and bad locations - whole thing take up to 2-3 minutes sometimes. And it works. No matter if phone is sleeping or not.
Now I'm reading about WakeLock and it doesn't make sense to me. How come my stuff is working? Is that coincidence?
How come my stuff is working?
A combination of things, including a dollop of luck. :-)
First, as Joel noted, the device wakes up briefly courtesy of your alarm, but the OS is only guaranteed to hold a WakeLock for the duration of onReceive() of a BroadcastReceiver.
It is possible that, at least on some versions of Android, requesting GPS updates causes the OS to acquire its own WakeLock. This is undocumented behavior AFAIK, and I have never relied upon it personally. If it does, though, and you are doing the rest of your work ("Wrap up, send data to server and shut down service") before removing location updates, that would explain the behavior.
There are still potential gaps in your approach (e.g., if you delegate to a Service to do the work and are not holding a WakeLock as part of passing control to that service). Statistically speaking, it may fail occasionally but work a lot of the time.
Personally, I recommend using a WakeLock, in case the undocumented behavior changes. That's what I do in LocationPoller.
Well reading from the AlarmManager documentation..
The Alarm Manager holds a CPU wake lock as long as the alarm
receiver's onReceive() method is executing.
Further...
Note: The Alarm Manager is intended for cases where you want to have
your application code run at a specific time, even if your application
is not currently running. For normal timing operations (ticks,
timeouts, etc) it is easier and much more efficient to use Handler.
So based on that.. I think it makes sense that it currently works; correct me if I'm wrong.