Schedule Jobs using JobScheduler in Android

The JobScheduler API allows to schedule jobs based on various conditions, not on exact time. These conditions can be whether the device is charging, idle, connected to a network or device’s battery level must not be low.

The job is created as a JobService subclass. We need to implement the onStartJob() and onStopJob() methods.

MethodDescription
onStartJob()Called when the system decides that job should be executed.

Method returns boolean value. Return true if job needs to continue running on a separate thread. In this case we need to call jobFinished() method to tell that the job was completed. Return false if job was completed by the end of onStartJob().

The long-running jobs should be executed on a separate thread because the onStartJob() method is performed on the main thread.
onStopJob()Called when the system decides that job should be stopped before was completed. It can happen if conditions are no longer met. For example, device was disconnected from the network.

Method returns boolean value. Return true if need to reschedule the job. Return false if job should be ended.

app/src/main/java/com/example/app/MyJobService.kt

package com.example.app

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

class MyJobService : JobService()
{
    override fun onStartJob(params: JobParameters): Boolean
    {
        Log.d("MY_APP", "Job started")

        Thread {
            for (i in 0..5) {
                Thread.sleep(1000)
                Log.d("MY_APP", "$i")
            }

            jobFinished(params, false)
        }.start()

        return true
    }

    override fun onStopJob(params: JobParameters): Boolean
    {
        return true
    }
}

In the manifest file we need to register a newly created JobService with the BIND_JOB_SERVICE permission.

app/src/main/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app">

    <application>
        <!-- ... -->
        <activity android:name=".MainActivity">
            <!-- ... -->
        </activity>
        <service android:name=".MyJobService"
            android:permission="android.permission.BIND_JOB_SERVICE" />
    </application>

</manifest>

A JobInfo object contains the scheduling conditions which is used to determine when the job should be executed. A JobInfo can be constructed using the JobInfo.Builder. It accepts the job ID that can be used to cancel the job or to monitor if job is still running. The JobScheduler object contains the schedule() method which is used to schedule the job.

app/src/main/java/com/example/app/MainActivity.kt

package com.example.app

import android.app.job.JobInfo
import android.app.job.JobScheduler
import android.content.ComponentName
import android.content.Context
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity()
{
    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val jobId = 1

        val jobService = ComponentName(this, MyJobService::class.java)
        val jobInfo = JobInfo.Builder(jobId, jobService)
            .setRequiresCharging(false)
            .setRequiredNetworkType(JobInfo.NETWORK_TYPE_NONE)
            .setMinimumLatency(1)   // Wait at least 1 ms
            .setOverrideDeadline(5) // Maximum delay 5 ms
            .build()

        val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
        jobScheduler.schedule(jobInfo)
    }
}

Leave a Comment

Your email address will not be published. Required fields are marked *