Note: -
- Before this define permission for notification inside AndroidManifest.xml file.
- And Ask user for notification permission if it is not allowed for app.
Add this into to HomeActivity Or MainActivity where first page opens after starting app
- use import android.Manifest for user permission check
// Declare the launcher at the top of your Activity/Fragment: private val requestPermissionLauncher = registerForActivityResult( ActivityResultContracts.RequestPermission(), ) { isGranted: Boolean -> if (isGranted) { // FCM SDK (and your app) can post notifications. } else { // TODO: Inform user that that your app will not show notifications. } } private fun askNotificationPermission() { // This is only necessary for API level >= 33 (TIRAMISU) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED ) { // FCM SDK (and your app) can post notifications. } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) { // TODO: display an educational UI explaining to the user the features that will be enabled // by them granting the POST_NOTIFICATION permission. This UI should provide the user // "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission. // If the user selects "No thanks," allow the user to continue without notifications. } else { // Directly ask for the permission requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) } } } fun getToken(){ FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task -> if (!task.isSuccessful) { Log.w("_MS_", "Fetching FCM registration token failed", task.exception) return@OnCompleteListener } // Get new FCM registration token val token = task.result // Log and toast Log.d("_MS_", token) // Toast.makeText(baseContext, token, Toast.LENGTH_SHORT).show() }) }
Don’t Forget to call askNotificationPermission() method from onCreate() method of Activity
Channels
- To create and show notification we need channels in our Application.
- Channels define how notification behavior and Importance while application is created.
- although user can change after application installed by going into application info.
- There Can be Multiple Categories to can be channel divided.
NotificationChannel()class creates channel object for application
- it take const id as String , Channel Name as String and Channel Importance inside constructor arguments to create channel .
- we can optionally set channel description later after channel created.
- then
manager.createNotificationChannel()takes channel object as argument can set that channel for the application.
Note:-
- Here App Class That Extends Application Created Separately because to use from all classes( Activities and Fragments ) from Application. reduce code duplication.
- And This Class need to be Registered Inside
AndroidManifest.xmlfile to be used.
- declare as an attribute of
<Application>tag.
android:name=".notifications.App" (.notification is package name in which App class resides) package com.example.roomwithcoroutine.notifications import android.app.Application import android.app.NotificationChannel import android.app.NotificationManager import android.os.Build // Register this inside AndroidManifest.xml file to use / found by Application /* Inside <Application> tag use attribute called android:name=".notifications.App" */ class App : Application() { // we will create two channel val CHANNEL_ID1 = "CHANNEL_ID1" val CHANNEL_ID2 = "CHANNEL_ID2" override fun onCreate() { super.onCreate() // before api lvl 26 there is no concept of channel // build version must be >= api lvl 26 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel1 = NotificationChannel(CHANNEL_ID1, "Channel 1", NotificationManager.IMPORTANCE_HIGH) channel1.description = "This is my High Important channel for notification" val channel2 = NotificationChannel( CHANNEL_ID2, "Channel 2", NotificationManager.IMPORTANCE_DEFAULT ) channel2.description = "This is my Default Important channel for notification" val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager manager.createNotificationChannel(channel1) manager.createNotificationChannel(channel2) // if you have multiple channels than // val channelList = arrayOf(channel1,channel2) // manager.createNotificationChannels(channelList.toMutableList()) } } }
Note:-
NotificationChanneldoes not work or exits on device below API lvl 26
- so make condition to check that or set minimum target device to API lvl 27
Basic Notification ( without Customization )
NotificationCompat.Builder()class is used to create Notification View Or content that shown on notification.
- it take two argument inside constructor
- Context
- Channel Id of channel it refers to.
- it has many other methods to customize Notification ,
- Here Basic notification is shown
notificationManager.notify()used to fire or launch notification to users device.
// High Priority Notification on Button Click binding.btnHigh.setOnClickListener { val notification = NotificationCompat.Builder(this@MainActivity, App().CHANNEL_ID1) notification.setContentTitle("Title Text") notification.setContentText("Notification Message Text") // set Notification Icon notification.setSmallIcon(R.drawable.baseline_mood_24) // set Priority notification.setPriority(NotificationCompat.PRIORITY_HIGH) // get Notification service from system as Notification Manager val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager // notify method will fire / send notification to device notificationManager.notify(1,notification.build()) } // Default Priority Notification On Button Click binding.btnLow.setOnClickListener { val notification = NotificationCompat.Builder(this@MainActivity, App().CHANNEL_ID2) notification.setContentTitle("Title Text") notification.setContentText("Notification Message Text") // set Notification Icon notification.setSmallIcon(R.drawable.baseline_mood_24) // set Priority notification.setPriority(NotificationCompat.PRIORITY_DEFAULT) // get Notification service from system as Notification Manager val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager // notify method will fire / send notification to device notificationManager.notify(2,notification.build()) }
Notification With Customization And Perform Some Action On Notification as well
⇒ addAction()
- It used to set / Add Action to perform some task from notification.
- We can Only define 3 actions To perform On Notification.
- it take Icon , text To display As Button to Click on Notification which will be shown depending upon users device but both are required.
- And Last it take Intent to perform task , That can be set null to disable action button.
⇒ Pending Intent getActivity()
- Pending Intent means that it will called in Future .
- Pending Intent bind intent that , it will be called in Future even if application is closed.
getActivity()method of PendingIntent class is used to create pending intent
getActivity()take this arguments context , request code as int , intent object and PendingIntent Flag.
- Flag should be
PendingIntent.FLAG_MUTABLEorPendingIntent.FLAG_IMMUTABLEif API level is greater or equals to 31. PendingIntent.FLAG_IMMUTABLEmeans it can not be change data after set once.PendingIntent.FLAG_MUTABLEmeans data can be change each time when notification is clicked or data passed.
Note:- android suggest that you should only use
PendingIntent.FLAG_MUTABLE if needed other you should other or IMMUTABLE if data are needed to change.- Data are set by using
putExtra()method of intent object.
⇒ setContentIntent()
- this method is used to perform action / intent on click of whole Notification.
- it take pendingIntent argument so it can be work even if application is closed.
- it some used to pass some data to application also.
- Example
binding.btnHigh.setOnClickListener { highPriorityNotification() } // inside class fun highPriorityNotification() { // it open same activity from this activity context val intentHigh = Intent(this, MainActivity2::class.java) // set data as you want intentHigh.putExtra("ABCD", "${binding.edtContent.text}") val pendingIntentHigh = PendingIntent.getActivity(this, 0, intentHigh, PendingIntent.FLAG_MUTABLE) val notification = NotificationCompat.Builder(this@MainActivity, App().CHANNEL_ID1) notification.apply { setContentTitle("${binding.edtTitle.text}") setContentText("${binding.edtContent.text}") setSmallIcon(R.drawable.baseline_mood_24) // set Notification priority setPriority(NotificationCompat.PRIORITY_HIGH) // set notification category setCategory(NotificationCompat.CATEGORY_MESSAGE) // set color for notification theme setColor(Color.MAGENTA) // define intent action/ task when click on notification. // it will take PendingIntent argument // - Pending Intent bind intent that , it will be called in Future even if application is closed. setContentIntent(pendingIntentHigh) // Only three action can br defined in notification // Action can be click to perform some task from notification. // task defined as intent that need to define // is set to null it assume as disable action addAction(R.drawable.baseline_mood_24, "back", null) addAction(R.drawable.baseline_mood_24, "Play", null) addAction(R.drawable.baseline_mood_24, "Next", null) // First Notification will pop-up if multiple notification occurs. setOnlyAlertOnce(true) // when click on notification it will close automatically when content are defined on click. setAutoCancel(true) } val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager notificationManager.notify(1, notification.build()) }