How to Set Up Weekly Notifications in Android: Recurring Notifications, Styling Options, and More.
Tags: android, notifications, kotlin, mobile
Published: 2023-04-10 15:02:45


As a developer, you know that user engagement is crucial for the success of your app. But how do you keep users coming back? One simple solution is to implement weekly notifications that remind them to use your app regularly. In this blog post, I'll walk you through the process of setting up weekly notifications for your app using Android's AlarmManager and Calendar classes. Whether you're building a productivity app, a fitness tracker, or a meditation guide, these notifications can help your users stay on track and achieve their goals.

![Screenshot of notification](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmvzhpkj1y1vwlni20kf.png)
This is what happens when you set the scheduled weekly notification (to 1213pm every monday).

This post will cover the following

- Creating Immediate Notifications
- Creating Weekly Notifications (doesn't repeat if user doesn't re-enter the app)
- Creating Recurring Notifications (repeats even if user doesn't re-enter the app)
- Styling the Notification

---

## Creating Immediate Notifications

For every notification we wil need to set up the following things Notification Manager, Channel (Id, Name and Importance), notification builder (where you add your notification details) and finally calling `.notify()` on the manager together with the builder to show the notification.

```kotlin
    fun triggerImmediateNotification(context: Context) {
        val notificationManager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        // create notification channel
        val channelId = "my_channel_id"
        val channelName = "My Channel"
        val importance = NotificationManager.IMPORTANCE_HIGH
        val channel = NotificationChannel(channelId, channelName, importance)
        notificationManager.createNotificationChannel(channel)

        // build notification (style it here)
        val notificationBuilder = NotificationCompat.Builder(context, channelId)
            .setSmallIcon(R.drawable.ic_notifications)
            .setContentTitle("My Notification Title")
            .setContentText("This is an immediate notification.")
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setAutoCancel(true)

        // set it to notify immediately
        val notificationId = 1
        notificationManager.notify(notificationId, notificationBuilder.build())
    }
```

---

## Creating Scheduled Weekly Notifications

Now to the part that we're all here for. How do we set up weekly notifications? We will move to our MainActivity for the below code, meaning this code will run everytime the user enters the app

#### Scheduling The Notification

What day of the week and time do you want to show the notification? We don't have to store this in preferences as if its within the same week it will always be set to sunday of this week.

```kotlin
// sunday 12pm in the afternoon
val calendar = Calendar.getInstance()
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY) // Sunday
calendar.set(Calendar.HOUR_OF_DAY, 12) // 12pm
calendar.set(Calendar.MINUTE, 0)
calendar.set(Calendar.SECOND, 0)
```

Then we need to check if the scheduled time has passed. This happens when user opens the app again after recieving a notification, we will want to reset the calendar day to the following week.

```kotlin
// Check if the scheduled time is in the past, if it is, add a week
if (calendar.timeInMillis < System.currentTimeMillis()) {
    calendar.add(Calendar.WEEK_OF_YEAR, 1)
}
```

Next, we will set up a intent which will be sent to the NotificationReciever Class which we will be working on later

```kotlin
val notificationIntent = Intent(this, NotificationReceiver::class.java)
notificationIntent.putExtra("notificationId", 1)
notificationIntent.putExtra("message", "Time to kick back, relax, and focus on your well-being. Don't forget to use our app to track your progress and goals. Let's make this week amazing together!")
notificationIntent.putExtra("title", "Self-Care Sunday!")
val pendingIntent = PendingIntent.getBroadcast(
    applicationContext,
    0,
    notificationIntent,
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
```

We will also need to set up the alarm manager to push the intent when the time comes.

```kotlin
val alarmManager = getSystemService(ALARM_SERVICE) as AlarmManager
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent) // will not repeat until user enters app again
```

#### Responding to Alarm and Notification: NotificationReciever Class
Now let's handle the intent that we scheduled initially

```kotlin
class NotificationReceiver : BroadcastReceiver() {
    // creates notification when it is time

    override fun onReceive(context: Context, intent: Intent) {
        val notificationId = intent.getIntExtra("notificationId", 0)
        val message = intent.getStringExtra("message")
        val title = intent.getStringExtra("title")

        val notificationManager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        val notificationBuilder = NotificationCompat.Builder(context, "my_channel_id")
            .setSmallIcon(R.drawable.ic_notifications)
            .setContentTitle(title)
            .setContentText(message)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setAutoCancel(true) // styling the notification

        notificationManager.notify(notificationId, notificationBuilder.build())
    }
}
```

---

## Creating Recurring Notifications
We will first create a function to schedule the notification based on a Calendar.

```kotlin
    private fun scheduleRecurringNotification(calendar: Calendar, title: Int, message: Int){
        // set recurring every 2 days
        val notificationIntent = Intent(this, NotificationReceiver::class.java)
        notificationIntent.putExtra("notificationId", 2)
        notificationIntent.putExtra("title", applicationContext.getString(title))
        notificationIntent.putExtra("message", applicationContext.getString(message))
        val pendingIntent = PendingIntent.getBroadcast(
            applicationContext,
            0,
            notificationIntent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )

        val alarmManager = getSystemService(ALARM_SERVICE) as AlarmManager
        val interval = 2 * 24 * 60 * 60 * 1000 // interval in milliseconds
//        val interval = 60000 // for every minute during testing

        alarmManager.
        setRepeating(
            AlarmManager.RTC_WAKEUP,
            calendar.timeInMillis,
            interval.toLong(),
            pendingIntent
        ) // repeating alarm (repeats every 2 days based on interval
    }
```

We will then use the function to schedule the notification like this
```kotlin
    fun scheduleEvery2DayNotification() {
        // will be reset when user uses the app, (if daily user, wont see notification)
        val calendar = Calendar.getInstance()
        calendar.set(Calendar.HOUR_OF_DAY, 21)
        calendar.set(Calendar.MINUTE, 0)
        calendar.set(Calendar.SECOND, 0)
        scheduleRecurringNotification(calendar, R.string.day2_notification_title , R.string.day2_notification_text)
    }
```

---

## Styling Notifications

As we mentioned earlier, we will using the notification builder to style the notification as well.

There are a few common customizations that I will be covering. Let's now try to make a notification like this.

![Parts of a Notification](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7acphx23svfj3krxa7d9.png)

```kotlin
val notificationBuilder = NotificationCompat.Builder(context, "my_channel_id")
    .setSmallIcon(R.drawable.icon) // small icon
    .setContentTitle(title) // content title
    .setContentText(message) // content text (this shows when the notification is not expanded)
    .setPriority(NotificationCompat.PRIORITY_HIGH)
    .setAutoCancel(true)
    .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.icon)) // you can also set a big icon on the right like how Gmail does it
    .setStyle(NotificationCompat.BigTextStyle()
        .bigText(message)) // this is the text shown when the notification is expanded
    .addAction(R.drawable.ic_notifications, "Write", pendingIntent) // adding actions (buttons)
    .setDefaults(NotificationCompat.DEFAULT_ALL)
```

More on styling Notifications here: [https://developer.android.com/develop/ui/views/notifications/expanded](https://developer.android.com/develop/ui/views/notifications/expanded)

---

Thanks for reading, leave a comment and let me know what you think! Hope that helps with creating notifications in Android! :)

## Socials
[Github](https://github.com/jolenechong/) [LinkedIn](https://www.linkedin.com/in/jolene-chong/) [Portfolio](https://jolenechong.netlify.app)