Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Schedule recurring job using firebase job dispatcher

I am trying to post the location of the android device to server every 10 minutes. I am using firebase job dispatcher to do this

FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(this));
Job myJob = dispatcher.newJobBuilder()
    .setService(UpdateLocationService.class)
    .setRecurring(true)
    .setTrigger(Trigger.executionWindow(10, 20))
    .setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
    .setTag("location-update-job")
    .setLifetime(Lifetime.FOREVER)
    .build();
dispatcher.mustSchedule(myJob);

UpdateLocationService gets the location and sends to server.

My problem: Things are mostly working fine. Only thing is, the jobs are getting scheduled with a difference of 4m, 6m, 7m, 8m, 10m, 16m, 23m...

Can some one please help me understand going on.

Update: I want the location once in 10-20 minutes. In the above code, the value is too low just for the testing purposes

like image 633
kranthi117 Avatar asked Nov 01 '16 09:11

kranthi117


3 Answers

There are a few reasons why this could be happening. Firstly is your job returning false in onStopJob()? From the docs

@Override
public boolean onStopJob(JobParameters job) {
    return false; // Answers the question: "Should this job be retried?"
}

If the job needs be retried then the backoff will be applied. Combine this with the fact you want it to run again every 10-20 seconds you might get the results you are experiencing.

You have not set any constraints for the job, which also will affect when it will run. e.g.

.setConstraints( // only run on an unmetered network Constraint.ON_UNMETERED_NETWORK, // only run when the device is charging Constraint.DEVICE_CHARGING )

Furthermore, I would not use a scheduled job for what you are doing. Look at the Google API Client which offers periodic updates from the fused location provider.

You can implement a callback on your Service or Activity like so

public class MainActivity extends ActionBarActivity implements
        ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
    ...
    @Override
    public void onLocationChanged(Location location) {
        mCurrentLocation = location;
        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
        updateUI();
    }

    private void updateUI() {
        mLatitudeTextView.setText(String.valueOf(mCurrentLocation.getLatitude()));
        mLongitudeTextView.setText(String.valueOf(mCurrentLocation.getLongitude()));
        mLastUpdateTimeTextView.setText(mLastUpdateTime);
    }
}

Checkout the full docs here but I believe you will have a more consistent experience with services dedicated to what you are trying to achieve.

https://developer.android.com/training/location/receive-location-updates.html

like image 130
Graham Smith Avatar answered Nov 15 '22 05:11

Graham Smith


Also the:

Trigger.executionWindow(windowStart, windowEnd)

expects the windowStart and windowEnd in seconds. As per your requirement, you want the window to be 10 mins. So you should use something like:

Trigger.executionWindow(10*60, 20*60)
like image 36
Mahesh Avatar answered Nov 15 '22 06:11

Mahesh


ExecutionWindow specifies approximate time. It's not guaranteed that job will run at the given window. If it misses the window the job will run at earliest time later under ideal circumstances.For recurring jobs once the job has finished next job will calculate execution window time from the time job last run.

LINK

ExecutionWindow represents a Job trigger that becomes eligible once the current elapsed time exceeds the scheduled time + the {@code windowStart} value. The scheduler backend is encouraged to use the windowEnd value as a signal that the job should be run, but this is not an enforced behavior.

like image 1
Android Developer Avatar answered Nov 15 '22 05:11

Android Developer