Scheduling android notifications

Himanshu Choudhary
4 min readDec 20, 2019

According to the Google android developers site: “ Notifications provide short, timely information about events in your app while it’s not in use”

What you will learn in this lesson?

  1. Automatically creating a notification after a certain period.
  2. Providing a button and a large image to that notification.
  3. Snoozing that notification for some time.

After creating your android project,

Step 1: Create a Notification Channel

Starting in Android 8.0 (API level 26), all notifications must be assigned to a channel. For each channel, you can set the visual and auditory behaviour that is applied to all notifications in that channel. Then, users can change these settings and decide which notification channels from your app should be intrusive or visible at all.

Click to know more about notification channel

  • Make a notification channel on your base activity or fragment so that it is present when you are loading your notification.
private fun createChannel(channelId: String, channelName: String) {
//create a channel
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(
channelId,
channelName,
// change importance of notication
NotificationManager.IMPORTANCE_HIGH
)//disable badges for this channel
.apply {
setShowBadge(false)
}

notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.RED
notificationChannel.enableVibration(true)
notificationChannel.description = getString(R.string.notification_channel_description)

val notificationManager = requireActivity().getSystemService(
NotificationManager::class.java
)
notificationManager.createNotificationChannel(notificationChannel)

}
}
  • You can also change the importance level according to your choice and set it in channel while creating it. Eg: NotificationManager.IMPORTANCE_HIGH
Notification importance levels

Starting with 8.0 (API level 26), notification badges (also known as notification dots) appear on a launcher icon when the associated app has an active notification. Users can long-press on the app icon to reveal the notifications (alongside any app shortcuts), as shown in the image.

  • I have disabled the badges by setting setShowBadge(false) you can also set it to true.
  • You can set any unique string value of channel Id and Channel Name and we will be using channel Id at the time of notification creation.

Note- Store string values in strings.xml file so that they can be manipulated easily if required.

  • Call the above function from OnCreate/OnCreateView
createChannel(
getString(R.string.notification_channel_id),
getString(R.string.notification_channel_name)
)

Step 2: Create two BroadcastReceiver

  • There will be two BroadcastReceiver i.e AlarmReceiver and SnoozeReceiver.
  • In our notification, we are displaying a title, a message, an image and a button which displays the same notification again after a minute.
  • AlarmManager will be triggered initially at the time of notification creation and after that by SnoozeReceiver every time you will click the button on the notification.
class AlarmReceiver: BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
// sendNotification
val notificationManager = ContextCompat.getSystemService(
context,
NotificationManager::class.java
) as NotificationManager

notificationManager.sendNotification(
context.getText(R.string.notification_msg).toString(),
context
)

}

}
  • sendNotification() is the extension that we will create in net step.
class SnoozeReceiver: BroadcastReceiver() {
private val REQUEST_CODE = 0

override fun onReceive(context: Context, intent: Intent) {
val triggerTime = SystemClock.elapsedRealtime() + DateUtils.MINUTE_IN_MILLIS // Time after which you want to show the //notification again

val notifyIntent = Intent(context, AlarmReceiver::class.java)
val notifyPendingIntent = PendingIntent.getBroadcast(
context,
REQUEST_CODE,
notifyIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
AlarmManagerCompat.setExactAndAllowWhileIdle(
alarmManager,
AlarmManager.ELAPSED_REALTIME_WAKEUP,
triggerTime,
notifyPendingIntent
)

val notificationManager = ContextCompat.getSystemService(
context,
NotificationManager::class.java
) as NotificationManager
notificationManager.cancelAll()
}

}
  • cancelAll() is the extension function that we will create later.

Step 3: Register both the receiver in the manifest file.

  • In the <application> ….. </application> tag, register both the receivers.
<receiver
android:name=".receiver.AlarmReceiver"
android:enabled="true"
android:exported="false">
</receiver>
<receiver
android:name=".receiver.SnoozeReceiver"
android:enabled="true"
android:exported="false">
</receiver>

Step 4: Create extension functions of the notification manager for creating and deleting the notification.

  • Create a kotlin file named ‘NotificationUtils’
  • In that file, add two functions as:
private val NOTIFICATION_ID = 0
private val REQUEST_CODE = 0
private val FLAGS = 0
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
// Create the content intent for the notification which launches the MainActivity

val contentIntent = Intent(applicationContext, MainActivity::class.java)
val contentPendingIntent = PendingIntent.getActivity(
applicationContext,
NOTIFICATION_ID,
contentIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)

val largeImage = BitmapFactory.decodeResource(
applicationContext.resources,
R.drawable.large_image
)
val bigPicStyle = NotificationCompat.BigPictureStyle()
.bigPicture(largeImage)
.bigLargeIcon(null)

// Add snooze action
val snoozeIntent = Intent(applicationContext, SnoozeReceiver::class.java)
val snoozePendingIntent: PendingIntent = PendingIntent.getBroadcast(
applicationContext,
REQUEST_CODE,
snoozeIntent,
FLAGS)
val builder = NotificationCompat.Builder(
applicationContext,
applicationContext.getString(R.string.notification_channel_id)
)
.setSmallIcon(R.drawable.app_icon)
.setContentTitle(applicationContext
.getString(R.string.notification_title))
.setContentText(messageBody)
.setContentIntent(contentPendingIntent)
.setAutoCancel(true)
.setStyle(bigPicStyle)
.setLargeIcon(eggImage)
.addAction(
R.drawable.button_icon,
applicationContext.getString(R.string.snooze),
snoozePendingIntent
)
.setPriority(NotificationCompat.PRIORITY_HIGH)
notify(NOTIFICATION_ID, builder.build())
}

/**
* Cancels all notifications.
*
*/
fun NotificationManager.cancelNotifications() {
cancelAll()
}

Step 5: To start the notification

  • First, cancel all the pending notification.
val notificationManager =
ContextCompat.getSystemService(
app,
NotificationManager::class.java
) as NotificationManager
notificationManager.cancelNotifications()
  • If you want to display the notification right away, you can use
val notificationManager =
ContextCompat.getSystemService(
app,
NotificationManager::class.java
) as NotificationManager
notificationManager.sendNotification(
context.getText(R.string.notification_msg).toString(),
context
)
  • If you want to display the notification after some time, you can make use of the AlarmReceiver as:
val notifyIntent = Intent(context, AlarmReceiver::class.java)
val notifyPendingIntent = PendingIntent.getBroadcast(
context,
REQUEST_CODE,
notifyIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
AlarmManagerCompat.setExactAndAllowWhileIdle(
alarmManager,
AlarmManager.ELAPSED_REALTIME_WAKEUP,
triggerTime,
notifyPendingIntent
)
  • Place the step 5 code on certain user action where you want the notification to display.

****************************************************************

Bonus: Watch whole notification tutorial by Google developers here

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

That’s all from my side for this part. If you have any doubts or suggestions please post it in the comments.

If you liked the article, hit the clap icon.

**************************HAPPY CODING**************************

--

--