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)

OUR VIDEO RECOMMENDATION

, ,

Migrating to Jetpack Compose – an interop love story

Most of you are familiar with Jetpack Compose and its benefits. If you’re able to start anew and create a Compose-only app, you’re on the right track. But this talk might not be for you…
Watch Video

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer for Jetpack Compose
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engin ...
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer f ...
Google

Jobs

No results found.

@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
Between platform changes, new rules, and Android customizations by OEMs, scheduling long-running background jobs…
READ MORE

Leave a Reply

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

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

Menu