Blog Infos
Author
Published
Topics
,
Published

Notifications provide short, timely information about events in your app while it’s not in use. This article shows you how to fetch data that includes your notification contents every 15 minutes using Work Manager and create a notification to show.

We have to do 3 steps to send the notification, LET’S DO IT.

1. Create a notification channel

First of all, you need to add the Supportive library:

dependencies {
    def core_version = "1.6.0"
    def work_version = "2.7.1"
    implementation "androidx.core:core:$core_version"
    implementation "androidx.work:work-runtime-ktx:$work_version"
    implementation 'androidx.hilt:hilt-work:1.0.0'

    kapt 'androidx.hilt:hilt-compiler:1.0.0'
}

Then for sending notifications we need to create a channel. We can create different channels to separate notification types, and users can turn them on and off as they want. For instance, sometimes they don’t need social notifications but need to be aware of the application’s latest news notifications.

To create a channel, you just need to do this as Google says:

private fun createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = getString(R.string.channel_name)
        val descriptionText = getString(R.string.channel_description)
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
            description = descriptionText
        }
        // Register the channel with the system
        val notificationManager: NotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

You may wonder what the ‘importance’ parameter is. This parameter determines how to interrupt the user for any notification that belongs to this channel. For more information about what the different levels mean, read about notification importance levels.

2. Create a worker

We need to fetch data from the server to get notifications if they are available. We can create a function and call it every 15 minutes, but wait! what if users leave the app? Then our application is in the background or even killed, So, how do we fetch data in those situations?! That’s where the Work Manager comes in. Let’s see how Work Manager helps us fetch the data while the app is in the background.

First, create an Instance of Work Manager.

val workManager = WorkManager.getInstance(application.applicationContext!!)

Second, set constraints.

val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresBatteryNotLow(false)
    .build()

Third, set data to pass to the worker.

val data = Data.Builder()
data.putString(ENDPOINT_REQUEST, endPoint)

Then, create the work.

val work = PeriodicWorkRequestBuilder<FetchDataWorker>(15, TimeUnit.MINUTES)
    .setConstraints(constraints)
    .setInputData(data.build())
    .build()

As we want to fetch data every 15 minutes from the server we should use PeriodicWorkRequestBuilder.

Finally, enqueue worker

workManager
    .enqueue(work)

Wait, where do we call our function to fetch data? That’s fairly simple: We put it in a class called ‘FetchDataWorker’. Our class should extend the Worker class to override the doWork() method. Rather than extending Worker, we extend CoroutineWorker to call suspend functions, as we want to collect data in a Flow. (read more here)

Job Offers

Job Offers


    Senior Android Engineer – Big Release Team

    Zalando SE
    Berlin
    • Full Time
    apply now

    Developer (m/w/d) Backend/ Mobile

    Payback GmbH
    Cologne, Germany
    • Full Time
    apply now

    Android Engineer

    ASOS
    London
    • Full Time
    apply now
Load more listings

OUR VIDEO RECOMMENDATION

, ,

The Evolution of Android Graphics in Android 12/13

Android 12 and 13 both added significant new capabilities to Android platform graphics, including RenderEffect, RuntimeShader, and more. At the same time, RenderScript has been deprecated and we’ve introduced the RenderScript Intrinsics Replacement Toolkit. This…
Watch Video

The Evolution of Android Graphics in Android 12/13

Daniel Galpin
Android Developer Advocate and Fast Talking YouTuber
Google

The Evolution of Android Graphics in Android 12/13

Daniel Galpin
Android Developer Ad ...
Google

The Evolution of Android Graphics in Android 12/13

Daniel Galpin
Android Developer Advocat ...
Google

Jobs

@HiltWorker
class FetchDataWorker @AssistedInject constructor(
    @Assisted appContext: Context,
    @Assisted workerParams: WorkerParameters,
    private val notificationViewModel: NotificationViewModel
) : CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {
        val endPoint = inputData.getString(NotificationCore.ENDPOINT_REQUEST)

        if (endPoint != null) {
            getData(endPoint)
        }

        val outputData = Data.Builder()
            .putString(NotificationCore.NOTIFICATION_DATA, "Hi Da")
            .build()

        return Result.success(outputData)
    }

You know what? I LOVE HILT. Why? Because it makes life easier. We need to call a function from notificationViewModel and we inject it into our worker class using hilt. Personally, I don’t even want to think about using the view model without the hilt in our worker class. Make sure to read more here.

3. Create a notification

Wow, we are ready to send notifications, look’s amazing.

In getData(endPoint) function we fetched data, our data should have three important attributes:

Id, title, and content.

This is how we send notifications.

val notifyIntent = Intent(this, ResultActivity::class.java).apply {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
notifyIntent.putExtra(NOTIFICATION_EXTRA, true)
notifyIntent.putExtra(NOTIFICATION_ID, notificationId)
val notifyPendingIntent = PendingIntent.getActivity(
        this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT
)

val builder = NotificationCompat
    .Builder(context, Channel_ID_DEFAULT)
    .setSmallIcon(notificationImage)
    .setContentTitle(notificationTitle)
    .setContentText(notificationContent)
    .setPriority(NotificationCompat.PRIORITY_HIGH)
    .setContentIntent(notifyPendingIntent)
    .setAutoCancel(true)

with(NotificationManagerCompat.from(context)) {
    notify(notificationId, builder.build())
}

We create a PendingIntent to start an activity when the user clicks on the notification. We can pass value using putExtra to our intent. To get extras when a notification is clicked, do this in your activity:

override fun onResume() {
        super.onResume()
        checkIntent(intent)
    }

    private fun checkIntent(intent: Intent?) {
        intent?.let {
            if (it.hasExtra(NotificationCore.NOTIFICATION_EXTRA)) {

                val id = it.getStringExtra(NotificationCore.NOTIFICATION_ID)

            }
        }
    }
}

Done. 🙂

My Notification Module Repository In Github

Don’t forget to give my repo a star and clap this article if you found it useful and I’ll be thankful if you share this article with your friends.

Which one do you prefer?

Also, there are other ways to send notifications like Firebase or OneSignal, but Which one do you prefer? Your own custom notifications library or third-party libraries?

This article was originally published on proandroiddev.com on February 28, 2022

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
Modern mobile applications are already quite serious enterprise projects that are developed by hundreds…
READ MORE
blog
Ask yourself a fairly standard question for any interview to fill an Android position:…
READ MORE
blog
Hey Android Devs, in this article we will go through a step by step…
READ MORE
blog
If you’ve been following my stories, this is the sequel of an article I’ve…
READ MORE

Leave a Reply

Your email address will not be published.

Fill out this field
Fill out this field
Please enter a valid email address.

Menu