Scheduling android notifications

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.

Step 1: Create a 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
  • 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.
  • Call the above function from OnCreate/OnCreateView
createChannel(
getString(R.string.notification_channel_id),
getString(R.string.notification_channel_name)
)
  • 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.
  • 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>
  • 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()
}
  • 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.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store