Android jobScheduler won't stop with jobFinished(params, false)

You have specified that a job is run periodically (every 60 seconds), so every 60~ seconds a new job is created and executed. jobFinished() is specific to a job, and simply indicates that it is done executing. You haven't cancelled anything.

Your (currently) accepted answer works for cancelling your scheduled job, but if all you want is a job that executes within 60 seconds and then stops, you should ommit setPeriodic() and use setOverrideDeadline(60000) instead. The job will run within 60 seconds and no more will be scheduled after it.


Well I figured it out if anyone else has this problem.

jobFinished() won't stop the periodic time you set from continuing. It just tells the job that you are finished, to release the wakelock, so Android doesn't have to kill the job off forcefully.

What I had to do was recreate the jobScheduler in my service and call cancelAll(). You could also apparently call cancel(job_id).

jobScheduler = (JobScheduler)this.getSystemService(Context.JOB_SCHEDULER_SERVICE );
jobScheduler.cancelAll();

I was using multiple JobService, and to stop one specific Job, I used the id of job to cancel the job.

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static void stopMyJob(Context context, int jobId) {
    JobScheduler scheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
    scheduler.cancel(jobId);
}

First I checked if the current job is active by or not, using the following function

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static boolean isJobActive(Context context, int jobId) {
    JobScheduler scheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
    boolean hasBeenScheduled = false;
    for (JobInfo jobInfo : scheduler.getAllPendingJobs()) {
        if (jobInfo.getId() == jobId) {
            hasBeenScheduled = true;
            break;
        }
    }
    return hasBeenScheduled;
}

While starting the job, I have the id passed to jobInfo as:

JobInfo jobInfo = new JobInfo.Builder(jobId, componentName);

The same jobid I used to stop the job by calling my function stopMyJob(context, jobID).

In most of cases, it's important to stop the current job and start the job again from beginning, if it's already running, for thais I used my both functions mentioned above as:

if (isJobActive(activity, ANNOUNCEMENT_JOB_ID)) {
    Log.d(TAG, "Job will cancel as already exist");
    stopMessagingJob(activity, ANNOUNCEMENT_JOB_ID);
    }
    startMyJob(activity, ANNOUNCEMENT_JOB_ID);

My startMyJob(context, jobId) looks like:

    private static void startMyJob(final Context context, final int jobId) {
            ComponentName componentName = new ComponentName(context, MyJobService.class);
                JobInfo jobInfo = new JobInfo.Builder(jobId, componentName)
                        .setPersisted(true).setPeriodic(TWENTY_MINUTES).build();
                JobScheduler scheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
                int resultCode = scheduler.schedule(jobInfo);
                if (JobScheduler.RESULT_SUCCESS != resultCode) {
                 Log.d(TAG, "Job failed to start");
                }
}