Firebase Jobdispatcher - Start now AND repeat - android

Per this example, I see that I can have the job start now using Trigger.NOW or a time of 0,0:
Bundle myExtrasBundle = new Bundle();
myExtrasBundle.putString("some_key", "some_value");
Job myJob = dispatcher.newJobBuilder()
// the JobService that will be called
.setService(MyJobService.class)
// uniquely identifies the job
.setTag("my-unique-tag")
// one-off job
.setRecurring(false)
// don't persist past a device reboot
.setLifetime(Lifetime.UNTIL_NEXT_BOOT)
// start between 0 and 60 seconds from now
.setTrigger(Trigger.executionWindow(0, 60))
// don't overwrite an existing job with the same tag
.setReplaceCurrent(false)
// retry with exponential backoff
.setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
// constraints that need to be satisfied for the job to run
.setConstraints(
// only run on an unmetered network
Constraint.ON_UNMETERED_NETWORK,
// only run when the device is charging
Constraint.DEVICE_CHARGING
)
.setExtras(myExtrasBundle)
.build();
dispatcher.mustSchedule(myJob);
My question is:
How do I set the job to start now but also repeat every [time interval] (lets call it 15 minutes)?

To make your job repeat periodically call these two methods:
.setRecurring(true) //true mean repeat it
.setTrigger(Trigger.executionWindow(start, end))
start : is know as windowStart, which is the earliest time (in seconds) the job should be considered eligible to run. Calculated from when the job was scheduled (for new jobs)
end : is know as windowEnd, The latest time (in seconds) the job should be run in an ideal world. Calculated in the same way as windowStart.

Related

Schedule a task weekly using Firebase job dispatcher

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.

General questions about JobScheduler

In my app I need to update user location by Geofire every 15 minutes continiously,but I am confused with some parameters.Currently I have
JobScheduler jobScheduler = (JobScheduler) getActivity().getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo.Builder builder = new JobInfo.Builder(AppConstants.USER_DATA_UPDATE_JOB_ID, new ComponentName(getActivity().getPackageName(), UserDataUpdateScheduler.class.getName()));
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
builder.setPeriodic(900000);
builder.setPersisted(true);
jobScheduler.schedule(builder.build());
What exactly indicates jobScheduler to start job again builder.setPeriodic(900000); or jobFinished(params, true); ? And also can't understand the meanings of onStartJob and onStopJob return values.
Also an additional question,in Android O a background service cannot receive location updates more than a few times per hour.So approxiamtely how much is that few times?
setPeriodic(long intervalMillis)
Specify that this job should recur with the provided interval, not more than once per period.In others words, this job must repeat with the interval assigned, in milis, 9000 = 9 seconds.
JobFinished
Call this to inform the JobScheduler that the job has finished its work. When the system receives this message, it releases the wakelock being held for the job.
setPeriodic(long intervalMillis)
Specify that this job should recur with the provided interval, not more than once per period the MinimumInterval for this method is 15 minutes or 900000 milliseconds
And
JobFinished
call when your job is Finished
(if your task is short write on onStart method and return false without calling JobFinished method )
note: if you define Your Job Periodic in jobFinished always return false

How do we use setMinimumLetancy using FirebaseJobDispatcher?

I am using FirebaseJobDispatcher for posting the data.
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(DetectedActivitiesIntentService.this));
Job myJob = dispatcher.newJobBuilder()
.setService(SendCarProbeDataService.class) // the JobService that will be called
.setTag(tripId)
.setConstraints(Constraint.ON_ANY_NETWORK)
.setExtras(bundle)
.build();
dispatcher.mustSchedule(myJob);
I have noticed that my posting service runs after some duration.
When I research on it, I get to know that there is a JobInfo which have the property to set setMinimumLetancy(0) to run the service as quick as possible.
JobInfo jobInfo = new JobInfo.Builder(tripId, SendCarProbeDataService.class)
.setMinimumLatency(0)
.setConstraints(Constraint.ON_ANY_NETWORK)
.setExtras(bundle).build();
But I need to know the difference between Job and JobInfo and how I use setMinimumLetancy in Job?
with job info you can specify the constraints of the job. if you want to execute your job at specific time then use
.setTrigger(Trigger.executionWindow(x, y))
x is the window starting time
y is the window ending time
eg:.setTrigger(Trigger.executionWindow(10, 20))
the job will execute between the time 10 to 20 seconds...
for immediate execution use
.setTrigger(Trigger.NOW)

Firebase Job Dispatcher not triggering at specified time, date as daily/weekly etc

Job myJob = dispatcher.newJobBuilder()
// the JobService that will be called
.setService(MyJobService.class)
// uniquely identifies the job
.setTag("my-unique-tag")
// one-off job
.setRecurring(true)
// don't persist past a device reboot
.setLifetime(Lifetime.FOREVER)
// start between 0 and 60 seconds from now
.setTrigger(Trigger.executionWindow(0, 60))
// don't overwrite an existing job with the same tag
.setReplaceCurrent(false)
// retry with exponential backoff
.setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
// constraints that need to be satisfied for the job to run
// .setConstraints(
// // only run on an unmetered network
// Constraint.ON_UNMETERED_NETWORK,
// // only run when the device is charging
// Constraint.DEVICE_CHARGING
// )
.setExtras(myExtrasBundle)
.build();
dispatcher.mustSchedule(myJob);
I am trying to use firebase jobdispatcher to support older devices and newer devices for my calendar app, i am referring this link to setup firebase code in my app is there anything needed to schedule job at particular time at daily weekly etc. or there any other alternative for that?
need help in trigger window setting to schedule event at particular time and date recursively. eg daily 4 pm event for 1 week
final int periodicity = (int)TimeUnit.HOURS.toSeconds(12); // Every 12 hours periodicity expressed as seconds
final int toleranceInterval = (int) TimeUnit.HOURS.toSeconds(1); // a small(ish) window of time when triggering is OK
Job myJob = dispatcher.newJobBuilder()
// the JobService that will be called
.setService(MyJobService.class)
// uniquely identifies the job
.setTag("my-unique-tag")
// one-off job
.setRecurring(true)
// persist past a device reboot
.setLifetime(Lifetime.FOREVER)
.setTrigger(Trigger.executionWindow(periodicity, periodicity + toleranceInterval))
// don't overwrite an existing job with the same tag
.setReplaceCurrent(false)
// retry with exponential backoff
.setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
// constraints that need to be satisfied for the job to run
// .setConstraints(
// // only run on an unmetered network
// Constraint.ON_UNMETERED_NETWORK,
// // only run when the device is charging
// Constraint.DEVICE_CHARGING
// )
.setExtras(myExtrasBundle)
.build();
dispatcher.mustSchedule(myJob);
add this line in menifiest file
<service
android:name="your service name"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true"/>
Calculate the time using as per your requirement and set the periodicity and toleranceInterval
int day = (int)TimeUnit.SECONDS.toDays(seconds);
long hours = TimeUnit.SECONDS.toHours(seconds) - (day *24);
long minute = TimeUnit.SECONDS.toMinutes(seconds) - (TimeUnit.SECONDS.toHours(seconds)* 60);
long second = TimeUnit.SECONDS.toSeconds(seconds) - (TimeUnit.SECONDS.toMinutes(seconds) *60);
1: Day calculation is correct does not require explanation.
2: TimeUnit.SECONDS.toHours(seconds) will give you direct conversion from seconds to hours without consideration for days you have already calculated. Minus the hours for days you already got i.e, day*24. You now got remaining hours.
3: Same for minute and second. You need to minus the already got hour and minutes respectively.

JobScheduler issues android

The jobscheduler runs every 10 mins periodically. What I have to do to run the schedule as soon as the app runs and keeps running periodically every 10 mins. What happens now is that: after the app is installed, it takes 10 mins to run the schedule. How to make it run initially and then repeats in every 10 mins? I have code for updating data to the server in onStartJob(). But the upload time is from 7 min to 25 mins too. I want to upload data every 10 mins but it varies randomly. Why is that?
JobInfo jobInfo =
new JobInfo.Builder(MYJOBID, jobService).setPeriodic(600000).
setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY).
setRequiresCharging(false).
setRequiresDeviceIdle(false).
setPersisted(true).
setExtras(bundle).
build();
int jobId = jobScheduler.schedule(jobInfo);
if(jobScheduler.schedule(jobInfo)>0){
Toast.makeText(LiveTrack.this,
"Successfully scheduled job: " + jobId,
Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(LiveTrack.this,
"RESULT_FAILURE: " + jobId,
Toast.LENGTH_SHORT).show();
}
.
public class MyJobService extends JobService {
#Override
public boolean onStartJob(JobParameters jobParameters) {
new MyDownloadTask().execute();
return false;
}
}
I want to upload data every 10 mins but it varies randomly. Why is that?
The JobScheduler API makes no promise of repeating at exact intervals.
But the upload time is from 7 min to 25 mins too.
According to setPeriodic() reference:
You have no control over when within this interval this job will be executed, only the guarantee that it will be executed at most once within this interval.
Still, we should be getting a callback at most 20 minutes apart. Let's look at JobInfo.Builder source code. Starting at setPeriodic(long):
public Builder setPeriodic(long intervalMillis) {
return setPeriodic(intervalMillis, intervalMillis);
}
Ok it calls it's overloaded cousin. Which says:
Specify that this job should recur with the provided interval and flex. The job can execute at any time in a window of flex length at the end of the period.
Wow so the flex length is also 10 minutes in our case? Not so fast:
/**
* Specify that this job should recur with the provided interval and flex. The job can
* execute at any time in a window of flex length at the end of the period.
* #param intervalMillis Millisecond interval for which this job will repeat. A minimum
* value of {#link #getMinPeriodMillis()} is enforced.
* #param flexMillis Millisecond flex for this job. Flex is clamped to be at least
* {#link #getMinFlexMillis()} or 5 percent of the period, whichever is
* higher.
*/
A minimum value of getMinPeriodMillis() is enforced.
:|
What is the minimum period you ask?
MIN_PERIOD_MILLIS = 15 * 60 * 1000L; // 15 minutes
So your call to setPeriodic(60000) doesn't accomplish anything. Minimum period remains clamped to 15 minutes.
JobScheduler is not really meant to be used for exact repeating periods. In fact it was built because a majority of the apps were abusing the AlarmManger api which provides this (exact repeating) functionality.

Categories

Resources