Job Scheduler Not Running on Android N

Job Scheduler not running on Android N

In Android Nougat the setPeriodic(long intervalMillis) method call makes use of setPeriodic (long intervalMillis, long flexMillis) to schedule periodic jobs.

As per the documentation:

JobInfo.Builder setPeriodic (long intervalMillis, long flexMillis)

Specify that this job should recur with the provided interval and
flex. The job can execute at any time in a window of flex length at
the end of the period.

intervalMillis long:
Millisecond interval for which this job will repeat. A minimum value of getMinPeriodMillis() is enforced.

flexMillis long:
Millisecond flex for this job. Flex is clamped to be at least getMinFlexMillis() or 5 percent of the period, whichever is higher.

Sample periodic job scheduled for 5 seconds:

private static final int JOB_ID = 1001;
private static final long REFRESH_INTERVAL = 5 * 1000; // 5 seconds

JobInfo jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setPeriodic(REFRESH_INTERVAL)
.setExtras(bundle).build();

The above code works well in Lollipop & Marshmallow but when you run in Nougat you will notice the following log:

W/JobInfo: Specified interval for 1001 is +5s0ms. Clamped to +15m0s0ms
W/JobInfo: Specified flex for 1001 is +5s0ms. Clamped to +5m0s0ms

Since we have set the periodic refresh interval to 5 seconds which is less than the thresholdgetMinPeriodMillis(). Android Nougat enforces the getMinPeriodMillis().

As a workaround, I'm using following code to schedule jobs at periodic intervals if job interval is less than 15minutes.

JobInfo jobInfo;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setMinimumLatency(REFRESH_INTERVAL)
.setExtras(bundle).build();
} else {
jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setPeriodic(REFRESH_INTERVAL)
.setExtras(bundle).build();
}

Sample JobService example:

public class SampleService extends JobService {
@Override public boolean onStartJob(JobParameters params) {
doSampleJob(params);
return true;
}

@Override public boolean onStopJob(JobParameters params) {
return false;
}

public void doSampleJob(JobParameters params) {
// Do some heavy operation
......
// At the end inform job manager the status of the job.
jobFinished(params, false);
}
}

Nougat - JobScheduler RESULT_SUCCESS but no output from job

Please try this:

// the service class

import android.app.job.JobParameters;
import android.app.job.JobService;
import android.util.Log;

/**
* JobService to be scheduled by the JobScheduler.
* start another service
*/
public class mService extends JobService {
private static final String TAG = "SyncService";

@Override
public boolean onStartJob(JobParameters params) {
Log.d("TAG", "onStartJobb");
return true;
}

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

// in main activity

@RequiresApi(api = Build.VERSION_CODES.N)
public void onResume(){
super.onResume();

JobScheduler scheduler = getSystemService(JobScheduler.class);

if(scheduler.getPendingJob(1) == null) {

ComponentName componentName = new ComponentName(this, mService.class);
//JobInfo.Builder builder = new JobInfo.Builder(0, serviceComponent);
JobInfo.Builder info = new JobInfo.Builder(1, componentName)
.setRequiresCharging(false)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setPersisted(true)
.setMinimumLatency(1 * 1000)
.setOverrideDeadline(3 * 1000)
//.setPeriodic(60 * 60 * 1000)
//.build()
;

int resultCode = scheduler.schedule(info.build());
if (resultCode == JobScheduler.RESULT_SUCCESS) {
Log.d("TAG", "Service is not running, Job " + String.valueOf(1) + " Scheduled.");
} else {
Log.d("TAG", "Service is not running, However job scheduling failed.");
}

} else{
Log.d("TAG", "Service is already scheduled.");
}
}

// and in manifest

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<service
android:name=".mService"
android:enabled="true"
android:exported="true"
android:label="Word service"
android:permission="android.permission.BIND_JOB_SERVICE">
</service>

Please download this samples and import the NotificationScheduler new project from there and check it. Please change your project accordingly.

What I noticed:

  1. the manifest entry is:

        android:name=".mService"
    android:permission="android.permission.BIND_JOB_SERVICE"
    ></service>
  2. the job scheduler:

    ComponentName serviceName = new ComponentName(getPackageName(), mService.class.getName());

    long min = JobInfo.getMinPeriodMillis();
    JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, serviceName)
    .setRequiredNetworkType(NETWORK_TYPE_NONE)
    .setRequiresDeviceIdle(false)
    .setPeriodic(5000)
    .setRequiresCharging(false);
    builder.setPeriodic(5 * 1000);

    JobInfo myJobInfo = builder.build();
    JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
    jobScheduler.schedule(myJobInfo);

Please note that here is a restriction for Periodic min interval, unfortunately it is 15 minutes, and when we set it smaller that, the SDK changes it to 15 minutes, and also it sets the flex interval 5 minutes, finally we get the service start after about 7-8 minutes from scheduling time of the Job. That is it ).

this works for me,

Good luck )

Periodic Job in Android N (Nougat, 7.0)

You should use https://developer.android.com/topic/libraries/architecture/workmanager/. This is new Android tool and it uses JobScheduler/AlarmManager and so on depending on situation.



Related Topics



Leave a reply



Submit