How to Direct reply on Notification in Android Studio using Kotlin.

Last updated Dec 20, 2021


In this article, we will see how to direct reply from notification like Whatsapp in Android Studio by using Kotlin Language.

Notification: A notification is a message displayed outside your app's UI by Android to offer the user with reminders, communication from other people, 
or other timely information from your app. Users can access your app or perform an action immediately from the notice by tapping it.

You might have seen this feature already in the very popular messaging app WhatsApp.

Implementation:

Step 1. 
Create a new Project in android studio.

Go to File > New > New Project > Empty Activity > Next > Enter Name > Select Language Kotlin > Finish.

 

Step 2. Go to activity_main.xml file and add the following code

  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/create"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Start" />
    
</RelativeLayout>


    

 

The UI will be like after adding above code:

Direct reply notification

 

Step 3. Open MainActivity.kt file and add the following code below setContentView(R.layout.activity_main).

val btn = findViewById(R.id.create)
        val channelId = "My_Channel_ID"
        val notificationId = 1
        createNotificationChannel(channelId)

 

        btn.setOnClickListener {
            if (Build.VERSION.SDK_INT >= 24) {
                // Create an instance of remote input builder
                val remoteInput: RemoteInput = RemoteInput.Builder("KEY_TEXT_REPLY")
                    .run {
                        setLabel("Write your message here")
                        build()
                    }

                // Create an intent
                val intent = Intent(this, NotificationReceiver::class.java)
                intent.action = "REPLY_ACTION"
                intent.putExtra("KEY_NOTIFICATION_ID", notificationId)
                intent.putExtra("KEY_CHANNEL_ID", channelId)
                intent.putExtra("KEY_MESSAGE_ID", 1)

                // Create a pending intent for the reply button
                val replyPendingIntent: PendingIntent = PendingIntent.getBroadcast(
                    this,
                    101,
                    intent,
                    PendingIntent.FLAG_UPDATE_CURRENT
                )

                // Create reply action and add the remote input
                var action: NotificationCompat.Action = NotificationCompat.Action.Builder(
                    R.drawable.ic_baseline_settings_24,
                    "Reply",
                    replyPendingIntent
                ).addRemoteInput(remoteInput)
                    .setAllowGeneratedReplies(true)
                    .build()


                // Build a notification and add the action
                val builder = NotificationCompat.Builder(this, channelId)
                    .setSmallIcon(R.drawable.home)
                    .setContentTitle("Developers")
                    .setContentText("Hi! How are you?")
                    .addAction(action)

                // Finally, issue the notification
                NotificationManagerCompat.from(this).apply {
                    notify(notificationId, builder.build())
                }
            }
        }
    }

    private fun createNotificationChannel(channelId:String) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            val name = "My Channel"
            val channelDescription = "Channel Description"
            val importance = NotificationManager.IMPORTANCE_DEFAULT

            val channel = NotificationChannel(channelId,name,importance)
            channel.apply {
                description = channelDescription
            }

            // Finally register the channel with system
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

In above code we defined some constant values like CHANNEL_ID, CHANNEL_NAME. Created Notification Channel, inside onCreate().

Added Click Listener event to create Button which is available in activity_main.xml file  and inside onClick method we defined the code for displaying the notification.

 if (Build.VERSION.SDK_INT >= 24) {
                // Create an instance of remote input builder
                val remoteInput: RemoteInput = RemoteInput.Builder("KEY_TEXT_REPLY")
                    .run {
                        setLabel("Write your message here")
                        build()
                    }

                // Create an intent
                val intent = Intent(this, NotificationReceiver::class.java)
                intent.action = "REPLY_ACTION"
                intent.putExtra("KEY_NOTIFICATION_ID", notificationId)
                intent.putExtra("KEY_CHANNEL_ID", channelId)
                intent.putExtra("KEY_MESSAGE_ID", 1)

                // Create a pending intent for the reply button
                val replyPendingIntent: PendingIntent = PendingIntent.getBroadcast(
                    this,
                    101,
                    intent,
                    PendingIntent.FLAG_UPDATE_CURRENT
                )

                // Create reply action and add the remote input
                var action: NotificationCompat.Action = NotificationCompat.Action.Builder(
                    R.drawable.ic_baseline_settings_24,
                    "Reply",
                    replyPendingIntent
                ).addRemoteInput(remoteInput)
                    .setAllowGeneratedReplies(true)
                    .build()


                // Build a notification and add the action
                val builder = NotificationCompat.Builder(this, channelId)
                    .setSmallIcon(R.drawable.home)
                    .setContentTitle("Developers")
                    .setContentText("Hi! How are you?")
                    .addAction(action)

                // Finally, issue the notification
                NotificationManagerCompat.from(this).apply {
                    notify(notificationId, builder.build())
                }
            }
        }

Right now you will see error on NotificationReceiver.class, as we haven’t created it yet.
 

Step 5. Create a new kotlin class and enter name (NotificationReceiver.kt) and click ENTER . Now, finally we need to handle the input, and other buttons in the notification. For this we will create a Broadcast Receiver.
.
 

Creating a Notification Action Handler

Add the following code to NotificationReceiver.kt file:

class NotificationReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        intent?.apply {
            if ("REPLY_ACTION".equals(action)){
                val message = replyMessage(this)
                val messageId = getIntExtra("KEY_MESSAGE_ID",0)
                Toast.makeText(context,"$messageId : $message",Toast.LENGTH_LONG).show()
            }

            context?.apply {
                val notificationId = getIntExtra("KEY_NOTIFICATION_ID",0)
                val channelId = getStringExtra("KEY_CHANNEL_ID")

                // Build a notification and add the action
                val builder = NotificationCompat.Builder(this, channelId.toString())
                    .setSmallIcon(R.drawable.ic_secure)
                    .setContentTitle("Successful")
                    .setContentText("Message sent!")

                // Finally, issue the notification
                NotificationManagerCompat.from(this).apply {
                    notify(notificationId, builder.build())
                }
            }
        }
    }


    private fun replyMessage(intent: Intent): CharSequence? {
        val remoteInput = RemoteInput.getResultsFromIntent(intent)
        return remoteInput?.getCharSequence("KEY_TEXT_REPLY")
    }
}

 

Step 6. We also need to define this receiver inside our AndroidManifest.xml file. So write the following xml code inside the tag.

        <receiver
            android:name=".NotificationReceiver"
          ></receiver>

 

Step 7. Run the app on emulator or real device, you will get the output as in Video.


Complete Source Code of Direct Reply on Notification Android Example 

activity_main.xml file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/create"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Start" />

</RelativeLayout>

 

MainActivity.kt file

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import android.app.PendingIntent

import android.content.Intent
import android.widget.Button
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.RemoteInput


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val btn = findViewById(R.id.create)
        val channelId = "My_Channel_ID"
        val notificationId = 1
        createNotificationChannel(channelId)

 

        btn.setOnClickListener {
            if (Build.VERSION.SDK_INT >= 24) {
                // Create an instance of remote input builder
                val remoteInput: RemoteInput = RemoteInput.Builder("KEY_TEXT_REPLY")
                    .run {
                        setLabel("Write your message here")
                        build()
                    }

                // Create an intent
                val intent = Intent(this, NotificationReceiver::class.java)
                intent.action = "REPLY_ACTION"
                intent.putExtra("KEY_NOTIFICATION_ID", notificationId)
                intent.putExtra("KEY_CHANNEL_ID", channelId)
                intent.putExtra("KEY_MESSAGE_ID", 1)

                // Create a pending intent for the reply button
                val replyPendingIntent: PendingIntent = PendingIntent.getBroadcast(
                    this,
                    101,
                    intent,
                    PendingIntent.FLAG_UPDATE_CURRENT
                )

                // Create reply action and add the remote input
                var action: NotificationCompat.Action = NotificationCompat.Action.Builder(
                    R.drawable.ic_baseline_settings_24,
                    "Reply",
                    replyPendingIntent
                ).addRemoteInput(remoteInput)
                    .setAllowGeneratedReplies(true)
                    .build()


                // Build a notification and add the action
                val builder = NotificationCompat.Builder(this, channelId)
                    .setSmallIcon(R.drawable.home)
                    .setContentTitle("Developers")
                    .setContentText("Hi! How are you?")
                    .addAction(action)

                // Finally, issue the notification
                NotificationManagerCompat.from(this).apply {
                    notify(notificationId, builder.build())
                }
            }
        }
    }

    private fun createNotificationChannel(channelId:String) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            val name = "My Channel"
            val channelDescription = "Channel Description"
            val importance = NotificationManager.IMPORTANCE_DEFAULT

            val channel = NotificationChannel(channelId,name,importance)
            channel.apply {
                description = channelDescription
            }

            // Finally register the channel with system
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
}

 

NotificationReceiver.kt file


import android.R
import android.widget.Toast
import android.app.RemoteInput
import android.content.Intent
import android.content.BroadcastReceiver
import android.content.Context
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat


class NotificationReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        intent?.apply {
            if ("REPLY_ACTION".equals(action)){
                val message = replyMessage(this)
                val messageId = getIntExtra("KEY_MESSAGE_ID",0)
                Toast.makeText(context,"$messageId : $message",Toast.LENGTH_LONG).show()
            }

            context?.apply {
                val notificationId = getIntExtra("KEY_NOTIFICATION_ID",0)
                val channelId = getStringExtra("KEY_CHANNEL_ID")

                // Build a notification and add the action
                val builder = NotificationCompat.Builder(this, channelId.toString())
                    .setSmallIcon(R.drawable.ic_secure)
                    .setContentTitle("Successful")
                    .setContentText("Message sent!")

                // Finally, issue the notification
                NotificationManagerCompat.from(this).apply {
                    notify(notificationId, builder.build())
                }
            }
        }
    }


    private fun replyMessage(intent: Intent): CharSequence? {
        val remoteInput = RemoteInput.getResultsFromIntent(intent)
        return remoteInput?.getCharSequence("KEY_TEXT_REPLY")
    }
}

 

 

AndroidManifest.xml file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your package name">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.DirectReply">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver
            android:name=".NotificationReceiver"
          ></receiver>
    </application>

</manifest>


Conclusion : In this article we have covered how to direct reply on notification in Android Studio by using Kotlin Language.


Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

68 Views

Subscribe For Daily Updates

Flutter Questions
Android Questions