Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
📱 Device Features  ·  Lesson 37

Notifications & Channels

Anatomy of a notification

9:41▮▮ 85%⏰ Maths homeworkStudent Diary · nowExercise 5.2, questions 1–10Mark doneSnooze🔔 Physics revisionStudent Diary · 1h
Small icon, title, text, app name, time and action buttons
PartBuilder method
Small icon (required)setSmallIcon()
Title / textsetContentTitle() / setContentText()
Long textsetStyle(BigTextStyle())
Tap actionsetContentIntent(pendingIntent)
ButtonsaddAction()

Step 1: Create a channel

Kotlin
val channel = NotificationChannel(
    "reminders",                                  // id – never change after release
    "Reminders",                                  // name shown in Settings
    NotificationManager.IMPORTANCE_HIGH           // heads-up + sound
).apply { description = "Homework and exam reminders" }
getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
Kotlin – StudentDiaryApp.kt (create it once at app start)
package com.codingeasily.studentdiary

import android.app.Application
import com.codingeasily.studentdiary.data.SettingsStore
import com.codingeasily.studentdiary.reminder.NotificationHelper

/**
 * Runs once when the app process starts (declared in AndroidManifest.xml).
 * We apply the saved light/dark theme and create the notification channel here.
 */
class StudentDiaryApp : Application() {
    override fun onCreate() {
        super.onCreate()
        SettingsStore(this).applyTheme()
        NotificationHelper.createChannel(this)
    }
}

Step 2: Permission (Android 13+)

Declare POST_NOTIFICATIONS in the manifest and request it at runtime on Android 13+ (see the Runtime Permissions lesson). On older versions it is granted automatically.

Step 3: Build and show

Kotlin – simplest notification
val notification = NotificationCompat.Builder(this, "reminders")
    .setSmallIcon(R.drawable.ic_notification)     // white, transparent background
    .setContentTitle("⏰ Maths homework")
    .setContentText("Due tomorrow at 9:00 AM")
    .setPriority(NotificationCompat.PRIORITY_HIGH)
    .setAutoCancel(true)                          // remove after tap
    .build()

NotificationManagerCompat.from(this).notify(101, notification)   // 101 = id (same id replaces)

Complete helper from Student Diary

Kotlin – reminder/NotificationHelper.kt
package com.codingeasily.studentdiary.reminder

import android.Manifest
import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import com.codingeasily.studentdiary.MainActivity
import com.codingeasily.studentdiary.R

object NotificationHelper {

    const val CHANNEL_ID = "reminders"

    /** Android 8+ needs a channel before any notification can be shown. */
    fun createChannel(context: Context) {
        val channel = NotificationChannel(
            CHANNEL_ID,
            context.getString(R.string.channel_reminders),
            NotificationManager.IMPORTANCE_HIGH
        ).apply { description = context.getString(R.string.channel_reminders_desc) }
        context.getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
    }

    fun canNotify(context: Context): Boolean =
        Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU ||
            ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) ==
            PackageManager.PERMISSION_GRANTED

    @SuppressLint("MissingPermission")          // we check canNotify() on the first line
    fun show(context: Context, noteId: Long, title: String, text: String) {
        if (!canNotify(context)) return

        // Tapping the notification opens the app
        val intent = Intent(context, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
        }
        val pending = PendingIntent.getActivity(
            context, noteId.toInt(), intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        val notification = NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle(title)
            .setContentText(text)
            .setStyle(NotificationCompat.BigTextStyle().bigText(text))
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setContentIntent(pending)
            .setAutoCancel(true)
            .build()

        try {
            NotificationManagerCompat.from(context).notify(noteId.toInt(), notification)
        } catch (e: SecurityException) {
            // permission was revoked while the app was running – ignore
        }
    }
}

Action buttons and progress

Kotlin
// "Mark done" button handled by a BroadcastReceiver
val doneIntent = Intent(this, MarkDoneReceiver::class.java).putExtra("noteId", note.id)
val donePending = PendingIntent.getBroadcast(this, note.id.toInt(), doneIntent,
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)

val builder = NotificationCompat.Builder(this, "reminders")
    .setSmallIcon(R.drawable.ic_notification)
    .setContentTitle("Maths homework")
    .addAction(R.drawable.ic_check, "Mark done", donePending)

// progress (e.g. uploading notes)
builder.setContentText("Uploading…").setProgress(100, 40, false)   // 40%
NotificationManagerCompat.from(this).notify(7, builder.build())

From reminder to notification

Save notedueAt = 9:00WorkManagerdelay until 9:00ReminderWorkerreads note from RoomNotificationHelpershow()User tapsMainActivity opens
Works even if the app was closed (next lesson)

Common mistakes

  • No channel → nothing appears on Android 8+.
  • Coloured or photo small icon → shows as a white square; use a simple white vector.
  • Missing FLAG_IMMUTABLE / FLAG_MUTABLE → crash on Android 12+.
  • Same notification id for different notes → they replace each other; use the note id.

Summary

  • Channel (once) → permission (13+) → NotificationCompat.Builder → notify(id, …).
  • PendingIntent for tap and action buttons, with FLAG_IMMUTABLE.
  • Keep the code in one helper object and reuse it.
✅ Practice

Add a "Test notification" button in Settings that shows a BigText notification which opens the app when tapped and has a "Mark done" action.

Frequently Asked Questions

Why is my notification not showing on Android 8+?
Every notification needs a channel on Android 8.0 (API 26) and above. Create the channel once (for example in your Application class) before showing notifications.
Can users turn off one type of notification?
Yes. Users control each channel separately in Settings, which is why you should create meaningful channels like "Reminders" and "Offers".
What is a PendingIntent?
A token that lets the system run your Intent later on your behalf — for example opening your Activity when the user taps the notification. Use FLAG_IMMUTABLE on Android 12+.
← Android Tutorial (Kotlin)
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Next topicWorkManager, Services & Broadcasts Your progress: 37 / 43 (86%) · Lesson 38 / 43 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free