In this android example tutorial, we will learn what is WorkManager and how to schedule tasks with WorkManager in android studio using kotlin language.
What is WorkManager?
WorkManager is a background processing library that is used to conduct background activities that must be completed in a certain amount of time but not necessarily immediately.
Using WorkManager We can enqueue our background processing when the app is not running and the device is reset for whatever reason. WorkManager also allows us to specify the
conditions that must be met in order for the task to be completed, such as network availability before beginning the background task.
WorkManager is one of the Android Architecture Components and is part of the Android Jetpack (a collection of libraries designed to assist developers create high-quality apps,
robust, testable,and easily maintainable apps).
Features of WorkManager:
WorkManager Implementation Demo Application to Schedule Tasks:
Step 1. Create a new Project in android studio.
Go to File > New > New Project > Google Maps Activity > Next > Enter Name > Select Language Kotlin > Finish. |
After creating the new project, Android Studio starts Gradle and builds your project, which may take a few seconds.
Step2. Add WorkManager dependency in app/buid.gradle file
For using WorkManager we have to add dependency in app/build.gradle file. So let’s open the app build.gradle file and add below lines.
implementation "android.arch.work:work-runtime:1.0.1" |
Step3. Open activity_main.xml file and add the following code
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <Button <Button <Button <Button |
This layout will contain TextView and Buttons. After that, we will set onClickListener() and this event will enqueue the WorkRequest to WorkManager and shows the status on TextView.
The above xml code will give you following output:
Step 4. We create a base class of Worker class and override un-implemented methods and super constructor.
For create a new Kotlin Class
app > java > com.example.workmanagerproject > right-click > new > Kotlin Class/File > Enter Name (NotificationWorker) > Enter. |
Add the following code to NotificationWorker.kt file
class NotificationWorker(context: Context, workerParams: WorkerParameters) : private fun showNotification(task: String, desc: String) { companion object { |
Step 5. Create WorkRequest
Let's move to MainActivity and initialize the views below setContentView(R.layout.activity_main).
tvStatus = findViewById(R.id.tvStatus) |
Make a WorkRequest to execute the work we just created. First, we'll make WorkManager. This work manager will manage and enqueue our work request.
mWorkManager = WorkManager.getInstance() |
Now we will create OneTimeWorkRequest, because we want to create a task that will be executed just once.
mRequest = OneTimeWorkRequest.Builder(NotificationWorker::class.java).build() |
Using this code, we built work request that will be executed one time only.
Enqueue the request with WorkManager
In this step, we discuss onClick() of the button. we will enqueue this request using the WorkManager. So that’s all we need to do.
mWorkManager!!.enqueue(mRequest!!) |
Fetch the particular task status
We'll get some information about this specific task and present it in the tvStatus TextView. We will accomplish this by use the WorkInfo class. The work manager exposes LiveData for each of the work request objects, which we can inspect to determine the task's current state.
mWorkManager!!.getWorkInfoByIdLiveData(mRequest!!.id).observe(this, { workInfo -> |
The MainActivity.kt file will be look after added above code:
class MainActivity : AppCompatActivity(), View.OnClickListener { private fun initViews() { override fun onClick(v: View) { companion object { |
Step 6. Now run the app in your emulator or real device, you will get the following output:
OUTPUT:
When clicked Send Notification without Constraints Button.
When clicked Send Notification with getRequiredNetworkType() Button
Complete Source Code of WorkManager with Example:
activity_main.xml file
<?xml version="1.0" encoding="utf-8"?> <Button <Button <Button <Button |
MainActivity.kt file
import androidx.appcompat.app.AppCompatActivity
private fun initViews() { override fun onClick(v: View) { companion object { |
NotificationWorker.kt file
import android.app.NotificationChannel class NotificationWorker(context: Context, workerParams: WorkerParameters) : private fun showNotification(task: String, desc: String) { companion object { |
build.gradle(app) file
plugins { android { defaultConfig { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" buildTypes { dependencies { implementation 'androidx.core:core-ktx:1.7.0' } |
Conclusion: In this article we have covered how to schedule tasks with WorkManager in Android Studio using Kotlin language.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<TextView
android:id="@+id/tvStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Result display here"
android:textSize="18sp" />
<Button
android:id="@+id/btnSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/purple_500"
android:layout_marginTop="20dp"
android:text="Send Notification without Constraints"
android:textAllCaps="false"
android:textColor="#fff" />
<Button
android:id="@+id/buttonStorageNotLow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/purple_500"
android:layout_marginTop="10dp"
android:text="Send Notification with requiresStorageNotLow()"
android:textAllCaps="false"
android:textColor="#fff"
/>
MainActivity.kt file
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.TextView import androidx.work.WorkManager import android.view.View import androidx.work.Constraints import androidx.work.NetworkType import androidx.work.OneTimeWorkRequest class MainActivity : AppCompatActivity(), View.OnClickListener { var tvStatus: TextView? = null var btnSend: Button? = null var btnStorageNotLow: Button? = null var btnBatteryNotLow: Button? = null var btnNetworkType: Button? = null var mRequest: OneTimeWorkRequest? = null var mWorkManager: WorkManager? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) initViews() } private fun initViews() { tvStatus = findViewById(R.id.tvStatus) btnSend = findViewById(R.id.btnSend) btnStorageNotLow = findViewById(R.id.buttonStorageNotLow) btnBatteryNotLow = findViewById(R.id.buttonBatteryNotLow) btnNetworkType = findViewById(R.id.buttonNetworkType) mWorkManager = WorkManager.getInstance() btnSend!!.setOnClickListener(this) btnStorageNotLow!!.setOnClickListener(this) btnBatteryNotLow!!.setOnClickListener(this) btnNetworkType!!.setOnClickListener(this) } override fun onClick(v: View) { tvStatus!!.text = "" val mConstraints: Constraints when (v.id) { R.id.btnSend -> mRequest = OneTimeWorkRequest.Builder(NotificationWorker::class.java).build() R.id.buttonStorageNotLow -> { /** * Constraints * If TRUE task execute only when storage's is not low */ mConstraints = Constraints.Builder().setRequiresStorageNotLow(true).build() /** * OneTimeWorkRequest with requiresStorageNotLow Constraints */ mRequest = OneTimeWorkRequest.Builder(NotificationWorker::class.java) .setConstraints(mConstraints).build() } R.id.buttonBatteryNotLow -> { /** * Constraints * If TRUE task execute only when battery isn't low */ mConstraints = Constraints.Builder().setRequiresBatteryNotLow(true).build() /** * OneTimeWorkRequest with requiresBatteryNotLow Constraints */ mRequest = OneTimeWorkRequest.Builder(NotificationWorker::class.java) .setConstraints(mConstraints).build() } R.id.buttonNetworkType -> { /** * Constraints * Network type is conneted */ mConstraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() /** * OneTimeWorkRequest with requiredNetworkType Connected Constraints */ mRequest = OneTimeWorkRequest.Builder(NotificationWorker::class.java) .setConstraints(mConstraints).build() } else -> { } } /** * Fetch the particular task status using request ID */ mWorkManager!!.getWorkInfoByIdLiveData(mRequest!!.id).observe(this, { workInfo -> if (workInfo != null) { val state = workInfo.state tvStatus!!.append( """ $state """.trimIndent() ) } }) /** * Enqueue the WorkRequest */ mWorkManager!!.enqueue(mRequest!!) } companion object { const val MESSAGE_STATUS = "message_status" } } |
NotificationWorker.kt file
import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context import android.os.Build import androidx.core.app.NotificationCompat import androidx.work.Data import androidx.work.Worker import androidx.work.WorkerParameters class NotificationWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { override fun doWork(): Result { val taskData = inputData val taskDataString = taskData.getString(MainActivity.MESSAGE_STATUS) showNotification("WorkManager", "Message has been Sent") val outputData = Data.Builder().putString(WORK_RESULT, "Jobs Finished").build() return Result.success(outputData) } private fun showNotification(task: String, desc: String) { val manager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val channelId = "task_channel" val channelName = "task_name" if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT) manager.createNotificationChannel(channel) } val builder = NotificationCompat.Builder(applicationContext, channelId) .setContentTitle(task) .setContentText(desc) .setSmallIcon(R.drawable.ic_launcher_background) manager.notify(1, builder.build()) } companion object { private const val WORK_RESULT = "work_result" } } |
build.gradle(app) file
plugins { id 'com.android.application' id 'kotlin-android' } android { compileSdk 31 defaultConfig { applicationId "com.example.workmanagerproject" minSdk 21 targetSdk 30 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } } dependencies { implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.4.0' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.2' implementation 'androidx.test:core-ktx:1.4.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' implementation "android.arch.work:work-runtime:1.0.1" } |
Conclusion: In this article we have covered how to schedule tasks with WorkManager in Android Studio using Kotlin language.
-->
Article Contributed By :
|
|
|
|
1142 Views |