Android Notification kotlin Example

Notifications provide short, timely information about events in your app while it's not in use
A notification is a message that Android displays outside your app's UI to provide the user with reminders, communication from other people, or other timely information from your app. Users can tap the notification to open your app or take an action directly from the notification.

Notification Anatomy



The most common parts of a notification are indicated above diagram as follows:
  1. SmallIcon :   This is set by calling setSmallIcon() .
  2. App Name :  This is by default provided by system .
  3. Time :  This is by default provided by system , It can be overridden by calline setWhen() or hide by calling setShowWhen(false) .
  4. Title :  This is set by calling setContentTitle() .
  5. Content :  This is set by calling setContentText() .
  6. LargeIcon :  This is set by calling setLargeIcon() .

val builder = NotificationCompat.Builder(applicationContext, channelId)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_launcher_round))
.setSmallIcon(R.drawable.ic_notifications_active)
.setContentTitle(title)
.setContentText(content)
.setPriority(priorty)
.setAutoCancel(true)
.setVibrate(longArrayOf(500, 500, 500))


Setting Pending Intent to Notification


 A PendingIntent is a token that you give to a foreign application which allows the foreign application to use your application's permissions to execute a predefined piece of code.

Create an explicit intent 
  // Create an explicit intent for an Activity in your app
        val intent = Intent(applicationContext, NotifyActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val extras = Bundle()
        extras.putString(NotifyActivity.notify_title, title)
        extras.putString(NotifyActivity.notify_content, content)
        intent.putExtras(extras)
        intent.action = Intent.ACTION_VIEW

A pending intent is a wrapper around regular intent that is designed to be used by another application. 
  val pendingIntent: PendingIntent =
            PendingIntent.getActivity(
                applicationContext,
                notificationID,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT
            )

and then set the pending to your notification builder 
	val builder = NotificationCompat.Builder(applicationContext, channelId)
				.setContentIntent(pendingIntent)


Notification Channel

  • Starting in Android 8.0 (API level 26), all notifications must be assigned to a channel or it will not appear.
  • Categorizing notifications into channels User can disable notification for particular category instead of all 
with(NotificationManagerCompat.from(applicationContext)) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val channel = NotificationChannel(
                    channelId,
                    channelName,
                    NotificationManager.IMPORTANCE_HIGH
                )
                channel.lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
                createNotificationChannel(channel)
            }
            // notificationId is a unique int for each notification that you must define
            notify(notificationID, builder.build())
        }


Notification importance


The possible importance levels are the following:
  1. Urgent: Makes a sound and appears as a heads-up notification.
  2. High: Makes a sound.
  3. Medium: No sound.
  4. Low: No sound and does not appear in the status bar. 

Play Notification Sound



    fun playNotificationSound(context: Context) {
        try {
            val defaultSoundUri =
                RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
            val r = RingtoneManager.getRingtone(context, defaultSoundUri)
            r.play()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


Lock Screen Notification


If you want notification to be shown even when device is locked it can be done by calling on notificationChannel reference .
 channel.lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC


Sample Example



Lets see sample example where we will have two activity one is MainActivity and another NotificationActivity 

  1.  In MainActivity we will have button on click of create notification and notify .
  2. When a notification is called launch NotificationActivity and retrieve notification data .

1. XML Layout


Create XML Layout inside res/layout/

1.a  XML Layout for MainActivity  

file : activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/politics"
        style="@style/btn_style"
        android:text="@string/channel_politics" />

    <Button
        android:id="@+id/sports"
        style="@style/btn_style"
        android:text="@string/channel_sports" />

    <Button
        android:id="@+id/entertainment"
        style="@style/btn_style"
        android:text="@string/channel_entertainment" />

</LinearLayout>

2.b XML Layout for NotificationActivity 

file :  activity_notify.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/notifyText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="22sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>


2. Activities


2.a MainActivity

file : MainActivity.kt
package com.tutorialsbuzz.notification

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.media.RingtoneManager
import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity(), View.OnClickListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setClickListener()
    }

    private fun setClickListener() {
        politics.setOnClickListener(this@MainActivity)
        sports.setOnClickListener(this@MainActivity)
        entertainment.setOnClickListener(this@MainActivity)
    }

    override fun onClick(view: View?) {

        when (view?.id) {

            R.id.politics -> {
                //Politics Notification
                createNotification(
                    resources.getString(R.string.channel_politics),
                    resources.getString(R.string.politics_content),
                    resources.getString(R.string.channel_politics),
                    NotificationCompat.PRIORITY_HIGH,
                    100
                )
            }

            R.id.sports -> {
                //Sports Notification
                createNotification(
                    resources.getString(R.string.channel_sports),
                    resources.getString(R.string.sports_content),
                    resources.getString(R.string.channel_sports),
                    NotificationCompat.PRIORITY_DEFAULT,
                    101
                )
            }

            R.id.entertainment -> {
                //Entertainment Notification
                createNotification(
                    resources.getString(R.string.channel_entertainment),
                    resources.getString(R.string.entertainment_content),
                    resources.getString(R.string.channel_entertainment),
                    NotificationCompat.PRIORITY_LOW,
                    102
                )
            }
        }
    }

    /**
     * Create Notification
     * Param
     * 1. title
     * 2. content
     * 3. channelId
     * 4.priorty
     * 5. notificationId
     */
    fun createNotification(
        title: String,
        content: String,
        channelId: String,
        priorty: Int,
        notificationID: Int
    ) {

        // Create an explicit intent for an Activity in your app
        val intent = Intent(applicationContext, NotifyActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val extras = Bundle()
        extras.putString(NotifyActivity.notify_title, title)
        extras.putString(NotifyActivity.notify_content, content)
        intent.putExtras(extras)
        intent.action = Intent.ACTION_VIEW

        val pendingIntent: PendingIntent =
            PendingIntent.getActivity(
                applicationContext,
                notificationID,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT
            )

        val builder = NotificationCompat.Builder(applicationContext, channelId)
            .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_launcher_round))
            .setSmallIcon(R.drawable.ic_notifications_active)
            .setContentTitle(title)
            .setContentText(content)
            .setContentIntent(pendingIntent)
            .setPriority(priorty)
            .setAutoCancel(true)
            .setVibrate(longArrayOf(500, 500, 500))


        with(NotificationManagerCompat.from(applicationContext)) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val channel = NotificationChannel(
                    channelId,
                    channelId,
                    NotificationManager.IMPORTANCE_HIGH
                )
                channel.lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
                createNotificationChannel(channel)
            }
            // notificationId is a unique int for each notification that you must define
            notify(notificationID, builder.build())
        }

        playNotificationSound(this@MainActivity)
    }

    /**
     * Play sound for notification
     */
    fun playNotificationSound(context: Context) {
        try {
            val defaultSoundUri =
                RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
            val r = RingtoneManager.getRingtone(context, defaultSoundUri)
            r.play()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}

 2.b NotifyActivity

file : NotifyActivity.kt
package com.tutorialsbuzz.notification

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_notify.*

class NotifyActivity : AppCompatActivity() {

    companion object {
        const val notify_title: String = "notify_title"
        const val notify_content: String = "notify_content"

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_notify)
        updateUI(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        updateUI(intent)
    }

    private fun updateUI(intent: Intent?): Unit {
        val title = (intent?.extras?.get(notify_title)) as String?
        val content = intent?.extras?.get(notify_content) as String?
        notifyText.text = title + "\n" + content
    }


}


No comments:

Post a Comment