9

I have a problem with jobs schedules with JobScheduler in new Android API 21. This is the code what I schedule the job with 60 seconds interval like below:

ComponentName serviceName = new ComponentName(this, MyJobService.class);
JobInfo jobInfo = new JobInfo.Builder(0, serviceName)
        .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
        .setPeriodic(60000)
        .build();

My JobService only print the time of runtime in Logcat, but the log show that service run in this moments:

03-18 08:37:26.334: I/JOB(32662): Wed Mar 18 08:37:26 BRT 2015
03-18 08:37:56.364: I/JOB(32662): Wed Mar 18 08:37:56 BRT 2015
03-18 08:39:21.418: I/JOB(32662): Wed Mar 18 08:39:21 BRT 2015
03-18 08:41:51.670: I/JOB(32662): Wed Mar 18 08:41:51 BRT 2015
03-18 08:45:52.192: I/JOB(32662): Wed Mar 18 08:45:52 BRT 2015
03-18 08:54:20.678: I/JOB(32662): Wed Mar 18 08:54:20 BRT 2015

It's strange because the Job it should execute at least 1 time within 1 minute as I set with setPeriodic(60000) method. It is also curious how the interval increases between runs. At this moment the time is Wed Mar 18 09:09:00 BRT 2015 and the Job don't be executed more.

Is it a problem with JobScheduler API? (I'm running in Nexus 5 with Android 5.0.1)

Dhaval Solanki
  • 4,589
  • 1
  • 23
  • 39
lucasb.aquino
  • 657
  • 1
  • 6
  • 10

3 Answers3

9

The time changing has to do with the Back-off Criteria for retrying jobs. By default it is set to exponential. I'm guessing that your also not correctly finishing your job when your done with it by calling jobFinished(JobParameters params, boolean needsReschedule).

I wrote a blog post which focus' on all of the little things with the JobScheduler. I highly recommend reading it.

MinceMan
  • 7,483
  • 3
  • 38
  • 40
  • Job Scheduler woks perfectly but if i lock the screen the time interval changes continuosly any solution to this which works for me – Jaichander Jun 11 '18 at 05:09
  • One thing the Job Scheduler doesn't do well is ensure exact times for your job to run. I think this would be a case of working as intended. By playing with your params you might be able to fix it though. Technically now you should use WorkManager instead. There was a Google IO talk on it a couple weeks ago. https://www.youtube.com/watch?v=IrKoBFLwTN0 https://developer.android.com/reference/kotlin/androidx/work/WorkManager – MinceMan Jun 12 '18 at 17:35
  • I have tried that, Issue is Work manager allows perodic Jobs 15 mins interval, I have to run job for every 60 seconds any other way i could achieve the result with exact Time frame, I have posted a question could you please ellobrate how to do it with out time lag https://stackoverflow.com/questions/50753823/android-i-am-facing-issue-while-setting-timertask-perodic-interval-when-app-is – Jaichander Jun 13 '18 at 07:00
5

I had the same problem and I think it might be connected with the internal requirements of JobInfo class:

Source code for JobInfo

    /* Minimum interval for a periodic job, in milliseconds. */
private static final long MIN_PERIOD_MILLIS = 15 * 60 * 1000L;   // 15 minutes

It looks like JobInfo won't allow you to put interval smaller than that.

1

//Below are the code I am using in my one of the project and it is working fine for me.

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public void scheduleJob(Context context) {
        //https://kb.sos-berlin.com/pages/viewpage.action?pageId=3638048
        //Scheduler uses UTC times for all its internal operations. This ensures a continual flow of operation without breaks or repetitions regardless of any changes in local time.
        JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, new ComponentName(context, MyService.class));//JobSchedulerService.class.getName()));
        builder.setPersisted(true); //persist across device reboots

        builder.setPeriodic((120 * 60 * 1000)); //run once after 2 hours seconds

        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); // only if wifi avaiblable so they are not using bandwith
        builder.setRequiresDeviceIdle(false); // run not only if the device is idle
        builder.setRequiresCharging(false); // run not only if the device is charging

       // android.os.PersistableBundle bundle = new android.os.PersistableBundle();
        // bundle.putString(WEB_SERVICE_URL, "http://example.com?upload.php");
        //   builder.setExtras(bundle);

        //builder.setBackoffCriteria(1600, JobInfo.BACKOFF_POLICY_LINEAR);
        //BACKOFF_POLICY_LINEAR After one failure retry at 1 * your value, then at 2 * (your value), then 3 * (your value) and so on
        //BACKOFF_POLICY_EXPONENTIAL After one failure retry at your value, then at (your value)^2, (your value)^3 and so on
        //builder.setMinimumLatency(5 * 1000); //latency
        //builder.setOverrideDeadline(50 * 1000); //wait for criteria to be met, in 50 seconds if they have not then run anyways


        int test = jobScheduler.schedule(builder.build());
        if (test <= 0) {
            Utility.showDialog(context, "Service Error", "Service is not responding");
            //If something goes wrong
        }
    }

We have defined service class per instructed below:

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class MyService extends JobService {

    @Override
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public boolean onStartJob(final JobParameters params) {

        Log.e(TAG, "onStartJob");

        String month = "3";
        String year = "2018";           
MyAsync myAsync = new MyAsync(MyService.this, arraydata, month, year, new SyncAsyncListener() {
                    @Override
                    public void onDataSuccess() {
                        try {
                            jobFinished(params, result);
                        } catch (Exception e) {

                        }
                    }
                });

                myAsync.execute();
            }
    return result;
}
@Override
public boolean onStopJob(JobParameters jobParameters) {
    return false;
}
}
Ramapati Maurya
  • 654
  • 9
  • 11