according to this medium article from Android Developers:
At the moment, if you need to execute a worker at roughly the same time, every day, your best option is to use a OneTimeWorkRequest with an initial delay so that you execute it at the right time:
and then when the work finishes successfully, the idea is to reschedule the work to be run once again and so on. now my question is that if we want a work to be repeated everyday at roughly the same time, why can't we directly use work manager PeriodicWorkRequest? for example suppose the work must be repeated everyday around 5:00 PM. then:
Calendar windowStart = new GregorianCalendar();
windowStart.set(Calendar.HOUR_OF_DAY, 17);
windowStart.set(Calendar.MINUTE, 0);
windowStart.set(Calendar.SECOND, 0);
windowStart.set(Calendar.MILLISECOND, 0);
long delay = windowStart.getTimeInMillis() - System.currentTimeMillis();
if (delay < 0) {
windowStart.add(Calendar.DAY_OF_MONTH, 1);
delay = windowStart.getTimeInMillis() - System.currentTimeMillis();
}
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
PeriodicWorkRequest periodicWorkRequest =
new PeriodicWorkRequest.Builder(Worker.class, 24, TimeUnit.HOURS, 5, TimeUnit.MINUTES)
.setInitialDelay(delay, TimeUnit.MILLISECONDS)
.setConstraints(constraints)
.build();
does this piece of code guarantee that the work will definitely run everyday between 17:00 and 17:05, if the constraints are met?
Related
I have set time interval in PeriodicWorkRequest 15 min but some time its executing before 15 min interval
This is my code
// START Worker
PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(LocationWorker.class, 15,
TimeUnit.MINUTES)
.addTag(TAG)
.build();
WorkManager.getInstance().enqueueUniquePeriodicWork("Location", ExistingPeriodicWorkPolicy.KEEP, periodicWork);
Please suggest what i did wrong or how can I execute my code exactly after 15 min
I'm using WorkManager to queue up OneTimeWorkRequests for file uploads. This of course requires network connectivity, and if the device does not have connectivity and the upload fails, it will retry as per my specified retry/backoff policy.
My question is simply:
Can I change the maximum backoff time for the retry?
The maximum backoff time is set to 5 hours by default and I would ideally like to reduce this, but I have not been able to find a way to do so.
See my code for enqueueing a work request below:
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
OneTimeWorkRequest uploadRequest = new OneTimeWorkRequest.Builder(UploadFileWorker.class)
.setInputData(createInputDataForUri(file.getPath()))
.setConstraints(constraints)
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL,
OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS)
.build();
workManager.enqueueUniqueWork(UNIQUE_WORK_FILE_UPLOAD, ExistingWorkPolicy.APPEND, uploadRequest);
We can easily set the BackoffPolicy (linear/exponential) and backoffDelay with .setBackoffCriteria(), as well as add an initial delay to the request, but I see no way to customise the maximum backoff time for the retry. Is this by design, or am I just blind?
I am developing and android app. This app has several activities. I need the application, regardless of which activity it displays, to execute a query on the server at 2 a.m. every day. I am currently using Timer and TimerTask, as follows:
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
public void run() {
makePostToServer()
}
};
timer.scheduleAtFixedRate(timerTask, getDate(), 1000 * 60 * 60 * 24); // 24 h
private Date getDate() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 1);
cal.set(Calendar.HOUR_OF_DAY, 2);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
return cal.getTime();
}
Is there a chance that for some reason a Timer launched at the start of the application will stop working?
Because the server logs do not always contain information about the executed query. It's as if it didn't happen.
Maybe there is a better way to call functions every day at 2.
Best regards
Instead of this use work manager for your need which is very efficient. In this case you can use periodic work manager.
Check out this for reference.
https://developer.android.com/topic/libraries/architecture/workmanager
Happy Coding!!
There are several APIs available to schedule tasks in Android:
Alarm Manager
Job Scheduler
GCM Network Manager
Firebase Job Dispatcher
Sync Adapter
You can find a lot of sample easily.
Have tried job dispatcher for scheduling repetitive tasks on Hourly basis. Have written a code snippet for the problem but not sure if this is a correct implementation or not.
Snippet is for scheduling a task at 11 Hour of Monday at every week.
Any correction on this or other possible solution will help a lot.
Calendar c1 = Calendar.getInstance();
c1.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
c1.set(Calendar.HOUR_OF_DAY, 11);
c1.set(Calendar.MINUTE, 0);
c1.set(Calendar.SECOND, 0);
c1.set(Calendar.MILLISECOND, 0);
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(Splash_onboarding.this));
Job myJob = dispatcher.newJobBuilder()
.setService(ScheduledNotificationService.class)
.setTag(dispatcherTag)
.setRecurring(true)
.setLifetime(Lifetime.FOREVER)
.setTrigger(Trigger.executionWindow(Math.round(c1.getTime().getTime() / 1000), (Math.round(c1.getTime().getTime() / 1000)) + 60))
.setReplaceCurrent(true)
.setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
.build();
dispatcher.mustSchedule(myJob);
I don't think you are implementing Firebase JobDispatcher correctly
Trigger.executionWindow()
In this, you write after how much time your job executes itself after scheduling your job. For more info see this :
https://stackoverflow.com/a/42111723/7384780
You can solve your problem by scheduling your first non-recurring job with executionWindow (get time of next monday) - System.currentTimeMillis() and then starting a recurring job inside JobService with executionWindow of 7 * 24 * 60 * 60.
i have to download json response from web server on every night,previously i have used AlarmManager for scheduling tasks but i think for this kind of situation JobDispatcher is great because it auto perform task if network available so i don't have to manage this kind of stuf.But i have found many examples of JobDispatcher and JobScheduler in all of them a simple job is scheduled or scheduled for some time delay but there is nothing relevant to my requirements,
if anyone have idea of this please help or provide any link related to this, it will be very helpful.
UPDATE
1. How to make this to work every night,because currently it is only set alarm to midnight for once , how to make it repeted for every night at same time ?
This is how you need to schedule time-based jobs
FirebaseJobDispatcher jobDispatcher = new FirebaseJobDispatcher(
new GooglePlayDriver(this));
Calendar now = Calendar.getInstance();
Calendar midNight = Calendar.getInstance();
midNight.set(Calendar.HOUR, 12);
midNight.set(Calendar.MINUTE, 0);
midNight.set(Calendar.SECOND, 0);
midNight.set(Calendar.MILLISECOND, 0);
midNight.set(Calendar.AM_PM, Calendar.AM);
long diff = now.getTimeInMillis() - midNight.getTimeInMillis();
if (diff < 0) {
midNight.add(Calendar.DAY_OF_MONTH, 1);
diff = midNight.getTimeInMillis() - now.getTimeInMillis();
}
int startSeconds = (int) (diff / 1000); // tell the start seconds
int endSencods = startSeconds + 300; // within Five minutes
Job networkJob = jobDispatcher.newJobBuilder()
.setService(NetworkJob.class)
.setTag(NetworkJob.ID_TAG)
.setRecurring(true)
.setTrigger(Trigger.executionWindow(startSeconds, endSencods))
.setLifetime(Lifetime.FOREVER)
.setReplaceCurrent(true)
.setConstraints(Constraint.ON_ANY_NETWORK)
.build();
jobDispatcher.schedule(networkJob);
I suggest you set your JobDispatcher to start at the next midnight, ie set the start time as the difference between now and the next midnight. Once it starts you can let it start a new Job that starts in 24 hours, ie the service will start a new Job with start time set as 24 hours and make this one recurring.