Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm tring to create a jobService. Here is what onStartJob() looks like.

@Override
public boolean onStartJob(JobParameters params) {
    Log.d(TAG, "onStartJob");
    Log.d(TAG, "Params= " + params.getJobId());
    param = params;
    jobFinished(params, false);
    //startAsync();
    return true;
}


@Override
public boolean onStopJob(JobParameters params) {
     Log.d(TAG, "onStopJob");
    return false;
}

Here is the code that is supposed to start the job.

public void startJobScheduler(){
    Log.d(TAG, "inside startJobScheduler");
    Activity activity = this.cordova.getActivity();
    Context context = activity.getApplicationContext();


     mJobScheduler = (JobScheduler)context.getSystemService(Context.JOB_SCHEDULER_SERVICE );
     JobInfo.Builder job = new JobInfo.Builder(111, new ComponentName(context, JobSchedulerService.class));

     job.setPeriodic(60000);
     Log.d(TAG, "before mJobScheduler.schedule(job.build())");
     if( mJobScheduler.schedule( job.build() ) <= 0 ) {
         Log.d(TAG, "job schedule failed");
     }
    Log.d(TAG, "333");
}

I can not get it to stop. It just keeps firing every 1-5 mins. I put jobFinished(params, false) in onStartJob() and commented out the task to try to kill it off right after it starts, but it just keeps firing. It seems jobFinished() fires something, as onDestroy() is called and my service gets destroyed, but then another job comes in with the same ID and starts it all back up.

I have BIND_JOB_SERVICE in the manifest like every example shows.

Any ideas on why jobFinished(params, false) doesn't seem to kill the setPeriodic(60000)?

like image 580
Daniel Braun Avatar asked May 27 '16 16:05

Daniel Braun


1 Answers

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");
                }
}
like image 76
HAXM Avatar answered Oct 02 '22 08:10

HAXM