I\'m trying to use the android Job Scheduler API and all I\'m trying to do is have the Job Scheduler run every 5 seconds. However when I run it, the corresponding service is
You need minimum 30 seconds to wait for next job
I was having this problem and after review some blogs and the official documentation, I realised that JobScheduler is having difference behavior on Android N(24 and 25). JobScheduler works with a minimum periodic of 15 mins.
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static void setJobScheduler(Context context){
Log.v(TAG, "Job Scheduler is starting");
JobScheduler jobScheduler = (JobScheduler)context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
ComponentName serviceName = new ComponentName(context, JobService.class);
JobInfo jobInfo;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setPeriodic(900000)
.build();
}else{
jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setPeriodic(Constants.TIME_INTERVAL)
.build();
}
jobScheduler.schedule(jobInfo);
}
From android documentation of setPeriodic ,
setPeriodic (long intervalMillis) : Specify that this job should recur with the provided interval, not more than once per period. 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.
so it is clearly mentioned that it is not necessary that job will run during this time. If you want to run a job at some periodic specific time , then you shoulf better use AlarmManager Api with setRepeating() method . Follow this link below for your requirements .
https://developer.android.com/training/scheduling/alarms.html#set
Instead of setPeriodic(int)
use setMinimumLatency(int)
with setOverrideDeadline(int)
. These two methods will adjust the interval of your JobScheduler
.
JobInfo.Builder builder = new JobInfo.Builder(1,new ComponentName(getPackageName(), JobSchedulerService.class.getName()));
builder.setPeriodic(3000);
MainActivity.java
public class MainActivity extends Activity {
private JobScheduler mJobScheduler;
private Button mScheduleJobButton;
private Button mCancelAllJobsButton;
@Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
mJobScheduler = (JobScheduler) getSystemService( Context.JOB_SCHEDULER_SERVICE );
mScheduleJobButton = (Button) findViewById( R.id.schedule_job );
mCancelAllJobsButton = (Button) findViewById( R.id.cancel_all );
mScheduleJobButton.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
JobInfo.Builder builder = new JobInfo.Builder( 1,
new ComponentName( getPackageName(), JobSchedulerService.class.getName() ) );
builder.setPeriodic( 3000 );
if( mJobScheduler.schedule( builder.build() ) <= 0 ) {
//If something goes wrong
}
}
});
mCancelAllJobsButton.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick( View v ) {
mJobScheduler.cancelAll();
}
});
}
}
just need to change
new JobInfo.Builder(1, new ComponentName(this, UpdateDatabaseService.class))
to
new JobInfo.Builder( 1, new ComponentName( getPackageName(), JobSchedulerService.class.getName() ) )
builder.setPeriodic( 3000 );
will setJobInfo
in 3000 ms schedule and called after every 3 seconds.
JobSchedulerService.java
public class JobSchedulerService extends JobService {
private Handler mJobHandler = new Handler( new Handler.Callback() {
@Override
public boolean handleMessage( Message msg ) {
Toast.makeText( getApplicationContext(), "JobService task running", Toast.LENGTH_SHORT ).show();
jobFinished( (JobParameters) msg.obj, false );
return true;
}
} );
@Override
public boolean onStartJob(JobParameters params ) {
mJobHandler.sendMessage( Message.obtain( mJobHandler, 1, params ) );
return true;
}
@Override
public boolean onStopJob( JobParameters params ) {
mJobHandler.removeMessages( 1 );
return false;
}
}
AndroidManifest.xml
<service android:name=".JobSchedulerService"
android:permission="android.permission.BIND_JOB_SERVICE" />
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/schedule_job"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Schedule Job"/>
<Button
android:id="@+id/cancel_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel All"/>
</LinearLayout>
You should call jobFinished(jobParams,needResheduleBoolean);
, after this call only the job will execute again, this is how the job knows it has finished execution so can start once more.