Android work manager :
In continuation to the previous tutorial we are proceeding with android work manager – periodic work request, i.e., when ever we want to do a work at a periodic interval of time we use this type of work request.
When the work request is initialised and assigned it will complete the task provided.
Even if the app is currently in use or not i.e., in foreground, background or even if the app is killed.
Also need to know that you can’t target a time for any task to be performed. And also instantly perform any task using work manager you may use AlarmManager or Foreground services for those actions.
Also in this blog i am going to provide code in terms of java and kotlin programming language so that it will be easy for you to implement irrespective of language.
Work manager periodic work request :
Periodic work request is used to make a background task run in periodic intervals of time making sure it honor’s the android doze mode policy’s in saving the battery life.
Also we can provide several constraints like battery charging level, device is in idle mode or not.
And even internet available is of limited or unlimited so that data is properly used according to the state of availability.
Project Structure :
Let us see project structure for android work manager periodic work request
Dependency :
We need to add work dependency’s required for android work manager.
def work_version = "2.3.4"
// Kotlin + coroutines implementation "androidx.work:work-runtime-ktx:$work_version" // optional - RxJava2 support implementation "androidx.work:work-rxjava2:$work_version" // optional - GCMNetworkManager support implementation "androidx.work:work-gcm:$work_version" // optional - Test helpers androidTestImplementation "androidx.work:work-testing:$work_version"
Periodic Work Request :
BackgroundTask.class
We need to extend a Worker class to make use of the worker class implementations.
Add a push notification module to let the user know the task status when alarm goes off here we need to take care of android version and handle accordingly.
Kotlin:
Providing the Kotlin source code for android work manager implementation.
import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context import android.os.Build import android.util.Log.d import androidx.core.app.NotificationCompat import androidx.work.Worker import androidx.work.WorkerParameters class BackgroundTask (context : Context, params : WorkerParameters) : Worker(context, params){ override fun doWork(): Result { d("oneTimeWorkRequest","Uploading photos in background") sendNotification("Background Task","Succcessfully done") return Result.success() } private fun sendNotification(title: String, message: String) { val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager //If on Oreo then notification required a notification channel. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel("default", "Default", NotificationManager.IMPORTANCE_DEFAULT) notificationManager.createNotificationChannel(channel) } val notification: NotificationCompat.Builder = NotificationCompat.Builder( applicationContext, "default" ) .setContentTitle(title) .setContentText(message) .setSmallIcon(R.mipmap.ic_launcher) notificationManager.notify(1, notification.build()) } }
Java :
Providing the java source code for android work manager implementation. You can easily get through the exact implementation of work manager rather than any complicated functionality.
import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.util.Log; import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; import androidx.work.Worker; import androidx.work.WorkerParameters; public class BackgroundTaskJava extends Worker { public BackgroundTaskJava(@NonNull Context context, @NonNull WorkerParameters workerParams) { super(context, workerParams); } @NonNull @Override public Result doWork() { Log.d("periodicWorkRequest","Uploading photos in background"); sendNotification("Background Task","Succcessfully done"); return Result.success(); } void sendNotification(String title, String message) { NotificationManager mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel("1", "android", NotificationManager.IMPORTANCE_DEFAULT); channel.setDescription("WorkManger"); mNotificationManager.createNotificationChannel(channel); } NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext(), "1") .setSmallIcon(R.mipmap.ic_launcher) // notification icon .setContentTitle(title) // title for notification .setContentText(message)// message for notification .setAutoCancel(true); // clear notification after click Intent intent = new Intent(getApplicationContext(), MainActivity.class); PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(pi); mNotificationManager.notify(0, mBuilder.build()); } }
activity_main.xml :
Just a simple view with a textview because this project is completely background task and output is shown through push notification
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.class
We will make declarations for making android work manager periodic work request
Kotlin :
kotlin code for periodic work request
import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity import androidx.work.* import java.util.concurrent.TimeUnit class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val constraints = Constraints.Builder().setRequiresCharging(true) .setRequiredNetworkType(NetworkType.UNMETERED).build() val periodicWorkRequest = PeriodicWorkRequest.Builder(BackgroundTask::class.java, 1, TimeUnit.SECONDS) .setInputData(Data.Builder().putBoolean("isStart", true).build()) .setInitialDelay(6000, TimeUnit.MILLISECONDS) .build() val workManager = WorkManager.getInstance(this) workManager.enqueue(periodicWorkRequest) workManager.getWorkInfoByIdLiveData(periodicWorkRequest.id).observeForever { if (it != null) { Log.d("periodicWorkRequest", "Status changed to ${it.state.isFinished}") } } } }
Java :
java code for the periodic work request
import android.os.Bundle; import android.util.Log; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.lifecycle.Observer; import androidx.work.Constraints; import androidx.work.NetworkType; import androidx.work.PeriodicWorkRequest; import androidx.work.WorkInfo; import androidx.work.WorkManager; import java.util.concurrent.TimeUnit; public class MainActivityJava extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Constraints constraints = new Constraints.Builder().setRequiresCharging(true).setRequiredNetworkType(NetworkType.UNMETERED).build(); final PeriodicWorkRequest periodicWorkRequest1 = new PeriodicWorkRequest.Builder(BackgroundTaskJava.class,1, TimeUnit.MILLISECONDS) .setInitialDelay(6000,TimeUnit.MILLISECONDS) .build(); WorkManager workManager = WorkManager.getInstance(this); workManager.enqueue(periodicWorkRequest1); workManager.getWorkInfoByIdLiveData(periodicWorkRequest1.getId()) .observe(this, new Observer<WorkInfo>() { @Override public void onChanged(@Nullable WorkInfo workInfo) { if (workInfo != null) { Log.d("periodicWorkRequest", "Status changed to : " + workInfo.getState()); } } }); } }
Output :
Finally we can see the notification popped up when the alarm goes off using android work manager.
If you have any query on android work manager do let us know in the comment section below.If you like this tutorial do like share for more interesting updates.