I need to running thread every one second. But when application killed, the thread must be still alive.
My thread task is used for increment Unix Timestamp (that synchronized when the first time application running from our server time) by one every second. I need to create this task because in some device, date time can changed unpredictable (maybe low on battery, hard reset, dropped or something else).
My Activity must be get that Unix Timestamp value when it needed.
From SO, Alarm Manager is not a good choice,
I would recommend you not to use an AlarmManager for 30 seconds, as some have suggested. Because 30 seconds is too short. it will drain the battery. For AlarmManager use a minimum 1 minute with RTC.
Other people suggest using Timer Task or ScheduledExecutorService, what the best thread to fit my need?
Thanks.
You would never achieve that. Any process could be killed by System. And task running every seconds is horrible (like AlarmManager said).
One idea is: save your server time and device time such as SystemClock.elapsedRealtime() . (do not use System.currentTimeMillis() for this purpose. ... this is display time for user and can be changed by user or something).
When you need time later, get elapsedRealtime() again and compare with stored elapsedRealtime(), and add this diff to stored server time. You will get desired time.
Or simply ask current time to your server , depends on needs :).
If you want to care hard reset I think that you should have database on your server to manage the first time when user launches app.
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.
In my system, user can create a schedule with time and conditions. Before 30 mins of schedule time, if the conditions are not satisfied the system will raise an alarm to notice users about that.
My system are spring boot applications and using spring scheduled task to trigger alarms. The problems is when user creates a lot of schedule in the future, if I create a scheduled task for each schedule data, there will be memory problem.
My current solution is a create a schedule run at a time of everyday to scan all data in next 24 hours and create scheduled task for them to trigger alarm. This will reduce scheduled tasks created but if user creates new schedule data in next 24 hours after scanning, that data will be not trigger any alarm.
So what should I do?
Is there a reason that you are scheduling all of this in JVM memory? If the JVM crashes (or is simply rebooted), the timers would then be lost as if the user never scheduled any alarm. As you mentioned, creating a timer per request would likely not be a scalable solution.
Without knowing the specific details of your system, the most common approach would be to persist (i.e. in a DB, flat file, etc.) the data each time a user requests to schedule event. This way, in the event of a crash or reboot, you won't lose events. Similarly, this approach can scale to multiple servers if necessary. Then, at whatever granularity you support (i.e. minute, hour, day, etc.) there would be a process or thread (only a single monitor thread) find all of the events which have expired since you last ran. Finally, once this thread has identified events that need an "alarm," this one thread can control sending these events for active processing. This thread can either individually handle each event or otherwise submit them to an active work queue for parallelization.
More specifically, if you have alarms which could go off at any minute, you should schedule a monitor thread to run every minute. This thread should find all the events which require an alarm and then actually send that alarm.
Remember that how often you should schedule your monitor thread is a function of the resolution you want for your alarms and your tolerance for late alarms. If late alarms are totally unacceptable, then your monitor must run at least as often as the finest granularity for scheduling an alarm event. This is, of course, assuming alarms are always scheduled in the future-- otherwise, you will probably want to double the frequency of your monitoring checks. To see why, consider the following example:
minute 0: Run monitor
minute 0: User schedules alarm for minute 0
minute 1: Run monitor
If we run the monitor once per minute but allow the user to schedule an alarm in the current minute, it's quite possible that we'll miss the event (as shown in the example above). I can go into this more deeply if necessary, but this is here mostly for completeness as I have no indications from your description that this will actually pose any problems.
Good luck.
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.
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.
I am using AlarmManager to poll user location periodically which is working fine- Now I would like to give my app users an option so they can restrict the location polling by specifying hours say 'Between 8PM to 10PM'.
Right now I am using AlarmManager.setRepeating method for scheduling but I am unable to configure my alarm service so that it runs every day but within certain hours.
I already know how to schedule a recurring task using AlarmManager at particular time of day but how to set the end time is what I am looking for.
You can't tell AlarmManager to do exactly that, but you could check whenever your service gets called to see if it's within the specified hours. If it is, then you proceed as normal, if not then you reschedule the alarm to start at the beginning of the next polling period.