Android Push

Learn how to implement push notifications.

Overview

There are two ways to implement push notifications on a device.

Find Your FCM Sender ID & FCM Server API Key

Firebase Cloud Messaging is a service that allows you to send notifications to your applications and receive information from them. Your FCM Sender ID and API key authenticates against CleverTap, enabling you to send notifications to your users from CleverTap.

To find your Sender ID and the API key, follow the steps:

  1. Log in to the Firebase Developer Console and go to your Dashboard.
  2. Click on the gear icon and access project settings.
12811281
  1. Go to the Cloud Messaging section, and you will have access to the sender ID and the API Key.
27502750

Set up Push Notifications Credentials

Follow these steps to enable push notifications:

  1. Navigate to Settings > Channel > Mobile Push.
  2. Enter the credentials.
10311031

Push Notifications for Android O

Android has modified sending push notifications to an app in the Oreo version. Starting with CleverTap SDK 3.1.7, we support Android Oreo's latest features like Notification Channels and Notification Badges.

Step 1: Prerequisites
Since Notification channels and badges are the features of the latest Android version, you as a developer will have to update your SDK and Build Tools to the latest versions. Make sure that in your build.gradle file, the compileSdkVersion is 26(or above) and buildToolsVersion is 26.0.1 (or above)

android {
   compileSdkVersion 26
   buildToolsVersion "26.0.1"
}

Step 2: Creating Notification Channels
Once the CleverTap Android SDK is integrated successfully, You can create stand-alone notification channels in your app by using the following line of code.

CleverTapAPI.createNotificationChannel(getApplicationContext(),"YourChannelId","Your Channel Name","Your Channel Description",NotificationManager.IMPORTANCE_MAX,true);

// Creating a Notification Channel With Sound Support
CleverTapAPI.createNotificationChannel(getApplicationContext(),"got","Game of Thrones","Game Of Thrones",NotificationManager.IMPORTANCE_MAX,true,"gameofthrones.mp3");

// How to add a sound file to your app : https://developer.clevertap.com/docs/add-a-sound-file-to-your-android-app
CleverTapAPI.createNotificationChannel(getApplicationContext(),"YourChannelId","Your Channel Name","Your Channel Description",NotificationManager.IMPORTANCE_MAX,true)

// Creating a Notification Channel With Sound Support
CleverTapAPI.createNotificationChannel(getApplicationContext(),"got","Game of Thrones","Game Of Thrones",NotificationManager.IMPORTANCE_MAX,true,"gameofthrones.mp3")

// How to add a sound file to your app : https://developer.clevertap.com/docs/add-a-sound-file-to-your-android-app

Step 3(Optional) : Creating Notification Channel Groups
Additionally, you can also create a notification channel group. Notification channel groups allow you to manage multiple notification channels with identical names within a single app, which is helpful if your app supports multiple accounts. You can create a notification group using the following line of code:

CleverTapAPI.createNotificationChannelGroup(getApplicationContext(),"YourGroupId","YourGroupName");
CleverTapAPI.createNotificationChannelGroup(getApplicationContext(), "YourGroupId", "YourGroupName")

Once you have created a notification channel group, you can use the group Id to create notification channels for that specific group. You can create a notification channel specifying the group id using the following line of code.

CleverTapAPI.createNotificationChannel(getApplicationContext(),"YourChannelId","YourChannelName","YourChannelDescription",NotificationManager.IMPORTANCE_MAX,"YourGroupId",true);
CleverTapAPI.createNotificationChannel(getApplicationContext(), "YourChannelId", "YourChannelName", "YourChannelDescription", NotificationManager.IMPORTANCE_MAX, "YourGroupId", true)

You can create more than one channel using the above lines of code. Just make sure that the channel ID differs in every Notification Channel. Also, this Channel ID will be used to send Push Notifications using the CleverTap dashboard.

Step 4: Deleting Notification Channels
You can delete the notification channels created previously in your app. There is no error thrown when you try to delete a notification channel that doesn't exist. You can delete the notification channels using the following line of code.

CleverTapAPI.deleteNotificationChannel(getApplicationContext(),"YourChannelId");
CleverTapAPI.deleteNotificationChannel(getApplicationContext(),"YourChannelId")

Step 5(Optional): Deleting Notification Groups
CleverTap SDK also allows you to remove the notification groups you have created previously. Note that you will need to delete all the channels associated with a group before deleting a group. You can delete a notification group using the following line of code:

CleverTapAPI.deleteNotificationChannelGroup(getApplicationContext(),"YourGroupId");
CleverTapAPI.deleteNotificationChannelGroup(getApplicationContext(),"YourGroupId")

Step 6: Sending Notifications via Dashboard
To send Push Notifications, login to the CleverTap Dashboard, and on the left navigation menu, click on Messages > Campaigns. Then click on the +Campaign button on the top right to select Mobile Push. Now, set up your Push Notification campaign by determining when you want to send out your notification, who you want to send it out to (in this case, it will be Android users), and what kind of push notification you want to send. Once you reach the what section, select the Single Message option. Select Send Message to Android O.

Fill in the Channel with the channel id you used to create the notification channel in your app. This field is mandatory as Android O requires a valid channel to send notifications. Badge Icon can be set as the app icon or the small icon to denote push notifications. The default is the app icon. Badge ID is the number you want to set the Notification Badge with. By default, it auto-increments. Both Badge Icon and Badge ID are optional.

15601560

📘

Notification Channel ID settings

You can choose a notification channel ID as optional or mandatory for creating a campaign. Select Add notification channels for Android 8.0 and above option. It is available at Settings>Integration>Push Notification. You can create a selection list of channel IDs for your messages.

14601460

Add CleverTap's FcmMessageListenerService

Inside the tags, register the following services:

<service
    android:name="com.clevertap.android.sdk.pushnotification.fcm.FcmMessageListenerService"
android:exported="true">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

For CleverTap SDK v3.4.3 and above, the CleverTap SDK supports specifying a custom FCM Sender ID. The SDK will request a token with the specified FCM Sender ID if it is present in the AndroidManifest.xml. If the FCM Sender ID is not available in the AndroidManifest.xml file, the SDK will request the token in the default manner, which uses the app's google-services.json file. To use a custom FCM Sender ID, add the following field in your app's AndroidManifest.xml:

❗️

`

The Custom FCM Sender ID feature has been discontinued in the versions of the CleverTap Android SDK after v4.3.1. CleverTap Android SDK only fetches the FCM token from the google-services.json file.

Opening a notification using CleverTap’s implementation will cause your app to be launched. If you send a deeplink, the link will be opened.

Add a Sound File to your Android App

Learn how you can add a sound file to your Android app, thereby allowing you to use custom sounds for your Android push notifications.

Android supports .mp3, .ogg and .wav files for playing custom sounds.

Adding Sound Files to Your Android Project

Right-click on Resources (res) folder and select New -> Android Resource Directory.

15501550

Select Resource Type as raw.

12681268

Put your MP3 file in the raw folder.

788788

Registering Notification Channel For the Custom Sound File

// Creating a Notification Channel With Sound Support
CleverTapAPI.createNotificationChannel(getApplicationContext(),"got","Game of Thrones","Game Of Thrones",NotificationManager.IMPORTANCE_MAX,true,"gameofthrones.mp3");
CleverTapAPI.createNotificationChannel(getApplicationContext(),"got","Game of Thrones","Game Of Thrones",NotificationManager.IMPORTANCE_MAX,true,"gameofthrones.mp3")

Creating Push Notifications with Custom Sounds

In the CleverTap dashboard, select Advanced > Custom Sound file and enter the name of your file with the extension in the text box.

📘

Note

If the notification channel has a custom sound, then this sound will always override the default OS sound.

19561956

Android 12 Changes

Android 12 (API 31) has rolled out new features and API changes. Refer to Android Behavior changes for Apps targeting Android 12.

There are changes for all apps, whether targeting API 31 or just running on Android 12. Some of these changes include Splash Screen API, Web intent resolution, and permissions, among others. You can find the complete list on the Android Developer documentation page.

📘

CleverTap Android SDK 4.3.0 supports Android 12

If you plan to increase the target API of your app to 31, you must upgrade CleverTap Android SDK to 4.3.0 or higher.

It is important to note that the following changes only target API 31.

Notification Trampolines

The system prevents components that start other activities inside services or broadcast receivers when a notification is opened. The system will prevent the activity from starting if this requirement is not met. The most prominent one is restrictions on Notification trampoline.

SDK Changes

The new restrictions on Notification Trampolines have changed how CleverTap handles some actions in SDK version 4.3.0. The most important change is the handling of push notifications.

Notification Body Click Handling

The push notification body is handled differently after the Android 12 update.

Android 11 and Lower

The PendingIntent is a unique instance that the CleverTap SDK creates inside each push notification. The Android OS identifies this instance to open the CTPushNotificationReceiver broadcast receiver. After opening the broadcast receiver, the CleverTap SDK completes the processing, such as starting the activity/deep-link and tracking the Notification Clicked event, and so on.

Android 12 and Above

Android has restricted the usage of Notification Trampolines. The push notification must start the activity directly after the notification tap. It means that the broadcast receiver or service is now redundant for opening the activity.

  • Automatic Handling by CleverTap SDK - When there is no target activity in the activity stack, the CleverTap SDK uses the onActivityCreated() method from com.clevertap.android.sdk.ActivityLifecycleCallback class to perform the following:

    • Raise the Notification Clicked event
    • Provide a callback to the application
  • Manual Handling by the Application - If a target activity is available in the activity stack, then you must handle these actions manually. For example, the payment screen is visible to the user, and the target activity of the deeplink is the payment screen. The onNewIntent() method can process the Notification Clicked event and provide the callback to the application using theclevertapApi.pushNotificationClickedEvent() method.

The following is an example of how you can set up actions in your application. Set up the automatic handling followed by the manual handling.

  1. For automatic handling, register the activity lifecycle callback using the ActivityLifecycleCallback.register(this method.
  2. For manual handling, override the onNewIntent() method in all your activities or the base activity and call the clevertapApi.pushNotificationClickedEvent().
class HomeScreenActivity : AppCompatActivity(){

override fun onNewIntent(intent: Intent?) {
   super.onNewIntent(intent)
   
   // On Android 12, Raise notification clicked event when Activity is already running in activity backstack
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
       cleverTapDefaultInstance?.pushNotificationClickedEvent(intent!!.extras)
        }
    }
}
class HomeScreenActivity extends AppCompatActivity {

   @Override
   protected void onNewIntent(final Intent intent) {
       super.onNewIntent(intent);
       /**
        * On Android 12, Raise notification clicked event when Activity is already running in activity backstack
        */
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
           cleverTapDefaultInstance.pushNotificationClickedEvent(intent.getExtras());
       }   
   }
}

The tables below show Notification Clicked handling in Android 12.

  • Without a deeplink or with an internal deeplink:

Application Running Status

Activity in Backstack

Activity not in Backstack

Foreground/Background

Call the clevertapApi.pushNotificationClickedEvent() method to raise notification clicks and callback from the onNewIntent callback.

The onActivityCreated callback from the com.clevertap.android.sdk.ActivityLifecycleCallback class raises the Notification Clicked event and provides a callback to the application.

Killed

Not Applicable.

The onActivityCreated callback from the com.clevertap.android.sdk.ActivityLifecycleCallback class raises the Notification Clicked event and provides a callback to the application.

  • With an external deeplink:

Application Running Status

Activity in Backstack

Activity not in Backstack

Foreground/Background

No Notification Clicks tracked.

No Notification Clicks tracked.

Killed

Not Applicable

No Notification Clicks tracked.

📘

Tracking Deeplinks

The notification trampoline restrictions mean that we cannot track the Notification Clicked events when the deeplinks point to a third-party application.

Notification CTA Click Handling

The handling for Push Notifications with an action button is the same as the handling for notifications body click. Additionally, when the Notification Clicked event is triggered, the event properties indicate the exact button click.

Android 11 and Lower

The PendingIntent is a unique instance that the CleverTap SDK creates inside each push notification. The Android OS identifies this instance to open the CTPushNotificationReceiver broadcast receiver. After opening the broadcast receiver, the CleverTap SDK completes the processing, such as starting the activity/deep-link and tracking the Notification Clicked event, and so on.

Android 12 and Above

Android has restricted the usage of Notification Trampolines in all OS versions above version 12. The push notification must start the activity directly after the notification tap. It means that the broadcast receiver or service is now redundant for opening the activity.

  • Automatic Handling by CleverTap SDK - When there is no target activity in the activity stack, the CleverTap SDK uses the onActivityCreated() method from the com.clevertap.android.sdk.ActivityLifecycleCallback class to perform the following:

  • Raise the Notification Clicked event

  • Provide a callback to the application

  • Manual Handling by the Application - If a target activity is available in the activity stack, then you must handle these actions manually. For example, the payment screen is visible to the user, and the target activity of deeplink is the payment screen. The onNewIntent() method can process the Notification Clicked event and provide the callback to the application using theclevertapApi.pushNotificationClickedEvent() method.

The following is an example of how you can set up actions in your application. Set up the automatic handling followed by the manual handling.

  1. For automatic handling, register the activity lifecycle callback using the ActivityLifecycleCallback.register(this) method.
  2. For manual handling, override the onNewIntent() method in all your activities or the base activity and call the clevertapApi.pushNotificationClickedEvent() method.
class HomeScreenActivity : AppCompatActivity(){

override fun onNewIntent(intent: Intent?) {
   super.onNewIntent(intent)
   
   // On Android 12, Raise notification clicked event when Activity is already running in activity backstack
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
       cleverTapDefaultInstance?.pushNotificationClickedEvent(intent!!.extras)
        }
    }
}
class HomeScreenActivity extends AppCompatActivity {

   @Override
   protected void onNewIntent(final Intent intent) {
       super.onNewIntent(intent);
       /**
        * On Android 12, Raise notification clicked event when Activity is already running in activity backstack
        */
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
           cleverTapDefaultInstance.pushNotificationClickedEvent(intent.getExtras());
       }
    }
}

The tables below show Notification Clicked handling in Android 12.

  • Without a deeplink or with an internal deeplink:

Application Running Status

Activity in Backstack

Activity not in Backstack

Foreground/Background

Call the clevertapApi.pushNotificationClickedEvent() method to raise notification clicks and callback from the onNewIntent callback.

The onActivityCreated callback from the com.clevertap.android.sdk.ActivityLifecycleCallback class raises the Notification Clicked event and provides a callback to the application.

Killed

Not Applicable.

The onActivityCreated callback from the com.clevertap.android.sdk.ActivityLifecycleCallback class raises the Notification Clicked event and provides a callback to the application.

  • With an external deeplink:

Application Running Status

Activity in Backstack

Activity not in Backstack

Foreground/Background

No Notification Clicks tracked.

No Notification Clicks tracked.

Killed

Not Applicable.

No Notification Clicks tracked.

📘

Tracking Deeplinks

The notification trampoline restrictions mean that we cannot track the Notification Clicked events when the deeplinks point to a third-party application.

Clear Notification on CTA Click

The clearing of notifications on CTA click is handled differently after the Android 12 update. The application must now handle these actions.

Android 11 and Lower

The PendingIntent is a unique instance that the CleverTap SDK creates inside each push notification. The Android OS identifies this instance to open the CTNotificationIntentService intent service. The CleverTap SDK then clears the notification.

Android 12 and Above

Android has restricted the usage of Notification Trampolines in all OS versions above version 12. The push notification must start the activity directly after the notification tap. It means that the broadcast receiver or service is now redundant for opening the activity.

  • Automatic handling by CleverTap SDK - This handling is not applicable for clearing a notification.

  • Manual handling by the application - There are two cases of manual handling for clearing notifications:

  • Target activity available in the activity stack - You must handle these actions manually. For example, the payment screen is visible to the user, and the target activity of deeplink is the payment screen. The onNewIntent() method can process the clearing of notifications.

  • Target activity not available in the activity stack - Register the activity lifecycle callbacks of the android.app.Application.ActivityLifecycleCallbacks class to clear the notification in the onActivityCreated method.

The following is an example of how you can clear notifications in your application:

class HomeScreenActivity : AppCompatActivity(){

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

   // On Android 12, clear notification on CTA click when Activity is already running in activity backstack
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
   NotificationUtils.dismissNotification(intent, applicationContext)
                    }
            }
}

class MyApplication : MultiDexApplication(),
ActivityLifecycleCallbacks {

override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {

// On Android 12, clear notification on CTA click when Activity is already running in activity backstack
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
   NotificationUtils.dismissNotification(intent, applicationContext)
                }
            }
}

object NotificationUtils {

   //Require to close notification on action button click
   fun dismissNotification(intent: Intent?, applicationContext: Context){
       intent?.extras?.apply {
            var autoCancel = true
            var notificationId = -1

            getString("actionId")?.let {
                Log.d("ACTION_ID", it)
                autoCancel = getBoolean("autoCancel", true)
                notificationId = getInt("notificationId", -1)
            }
            /**
             * If using InputBox template, add ptDismissOnClick flag to not dismiss notification
             * if pt_dismiss_on_click is false in InputBox template payload. Alternatively if normal
             * notification is raised then we dismiss notification.
             */
            val ptDismissOnClick = intent.extras!!.getString(PTConstants.PT_DISMISS_ON_CLICK,"")

            if (autoCancel && notificationId > -1 && ptDismissOnClick.isNullOrEmpty()) {
                val notifyMgr: NotificationManager =
                    applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                notifyMgr.cancel(notificationId)
            }
        }
   }
}
class HomeScreenActivity extends AppCompatActivity {

   @Override
   protected void onNewIntent(final Intent intent) {
       super.onNewIntent(intent);
       
       /**
        * On Android 12, clear notification on CTA click when Activity is already running in activity backstack
        */
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
           NotificationUtils.dismissNotification(intent, applicationContext);
       }
   }
}

class MyApplication extends MultiDexApplication implements ActivityLifecycleCallbacks {

   @Override
   public void onActivityCreated(@NonNull final Activity activity, @Nullable final Bundle savedInstanceState) {

/**
        * On Android 12, clear notification on CTA click when Activity is already running in activity backstack
        */
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
           NotificationUtils.dismissNotification(intent, applicationContext);
       }

   }

}

public class NotificationUtils {

//Require to close notification on action button click
   public static void dismissNotification( Intent intent, Context applicationContext){
       Bundle extras = intent.getExtras();
       if (extras != null) {
           String actionId = extras.getString("actionId");
           if (actionId != null) {
               boolean autoCancel = extras.getBoolean("autoCancel", true);
               int notificationId = extras.getInt("notificationId", -1);
               if (autoCancel && notificationId > -1) {
                   NotificationManager notifyMgr =
                           (NotificationManager) applicationContext.getSystemService(Context.NOTIFICATION_SERVICE);
                   notifyMgr.cancel(notificationId);                }
              
           }
       }
   }
}

Other Android 12 Changes

Pending Intents Mutability

To improve the security of your app, you must specify the mutability of each PendingIntent object that your app creates. CleverTap Android SDK 4.3.0 complies with this.

Safer Component Exporting

You must explicitly declare the android:exported attribute if your app contains activities, services, or broadcast receivers that use intent filters. Refer to Safer Component Exporting. CleverTap Android SDK 4.3.0 complies with this.

Custom Notifications

To streamline User Experience when apps use entirely Custom Notification layouts, Android 12 will prevent such notifications from using the whole notification area.
Android 12 introduces a standard template for notifications, ensuring the same decoration for all notifications. It has a fixed header with the app name and a consistent expand/collapse appearance.
Detailed documentation and illustration are available in the Android user experience documentation.
CleverTap Push Templates SDK will be released soon, supporting Android 12 changes related to Custom Notifications.

Set the Small Notification Icon

The small icon is a notification bar icon displayed in the push notifications, as shown in the image below:

10801080

With the launch of Android 5 (Lollipop), the notification icons are rendered differently in the notification bar at the top. By default, our SDK uses the app's icon for both the notification icon and the notification bar icon; however, since Android 5, all non-alpha channels are ignored while drawing the main notification icon. For more information, refer to Material design style in the Android documentation.

The small icon must be an alpha only image, which means the icon must have only one color, and the rest must be transparent. The alpha only icon image combines the colored and transparent regions.

In general, the logo displayed in the icon has a single color, and the background is transparent. The alpha channel provides the ability to embed transparency within an image. This can be accomplished with tools such as Adobe Photoshop, Illustrator, and so on. You can also change the colored region of the small icon from the CleverTap dashboard.

The CleverTap SDK fills the transparent section of the small icon with the selected color:

27362736

Following is a small icon sample:

3636

After creating an icon with the alpha channel, you can use it for your project in Android Studio. Save the icon file in the Drawable folder of your project.

To set a custom notification icon (only for the small icon), add the following metadata entry in your AndroidManifest.xml.

<meta-data
    android:name="CLEVERTAP_NOTIFICATION_ICON"
    android:value="ic_stat_red_star"/> <!-- name of your file in the drawable directory without the file extension. -->

❗️

Warning

Use only the file name. Do not use the path such as @drawable/ic_stat_red_star .

Push Notification Callback

The CleverTap Android SDK v3.8.1 SDK gives you a callback when a Push Notification is clicked along with the entire payload. Implement the CTPushNotificationListener in your Application class or Main Activity to receive this payload.

To set the listener, use the following code -

CleverTapAPI cleverTapAPI = CleverTapAPI.getDefaultInstance(getApplicationContext());
cleverTapAPI.setCTPushNotificationListener(this);
CleverTapAPI.getDefaultInstance(applicationContext)?.apply {
    ctPushNotificationListener = [email protected]
}

Implement the following override method to receive the payload as a Map on the click of a notification -

@Override
public void onNotificationClickedPayloadReceived(HashMap<String, Object> payload) {
   //Use your custom logic for  the payload 
}
override fun onNotificationClickedPayloadReceived(payload: HashMap<String, Any>?) {
    //Use your custom logic for  the payload 
}

Advanced Android Push Notification Options

Apart from the Title and Message, you have the below-mentioned options to add to your Android push notification. Note that each of these is optional.

Image URL

If an image link is specified, a large image is added to your push notification.

  • Recommended resolution: 600×300
  • Max size: 40 kb
  • Supported file formats are .jpg and .png

Large Icon URL

If a large icon link is specified, the large icon will be appended to the push notification. The large icon will be displayed either far left or far right based on the device.

  • Max resolution – 72×72
  • Max size – 1 kb

Deeplink/External URL

A deeplink helps you open a particular activity in your app after a click on the notification. If left empty, the notification on click will open the launcher activity of the app.

To use external URLs, whitelist the IPs or prefix the URL with http or https. For more information, refer to Deeplinking.

Action Buttons

You can add up to three call to action buttons for every push notification. For every action button, you have the following options:

  • Title: contains the Call to Action text (mandatory)
  • Deeplink: the deeplink that should open on click of that button
  • Action ID: a user-defined string (applicable to apps custom handling their android push notifications: This string will be available as an extra on the notification click intent for you to identify the action button clicked). This is a mandatory field.
  • Icon Resource Identifier: A drawable icon in your app’s resources folder to display the icon along with the notification for Android devices below OS version Nougat. Android Nougat does not display icons by default to allow more buttons.

If the user clicks on the main body of the notification, the app will open, and the notification will disappear. If the user clicks on one of the action buttons, then by default, Android will not remove the notification from the tray. We provide two user options for this.

The first option is to handle closing the notification yourself (applies to apps that are custom handling the push notification). The click intent has the notification Id in its extras to accomplish this. So to close, add the following code in the activity that would get called.

Bundle extras = intent.getExtras();
if (extras != null) {
    String actionId = extras.getString("actionId");
    if (actionId != null) {
        Log.d("ACTION_ID", actionId);
        boolean autoCancel = extras.getBoolean("autoCancel", true);
        int notificationId = extras.getInt("notificationId", -1);
        if (autoCancel && notificationId > -1) {
            NotificationManager notifyMgr =
                    (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
            notifyMgr.cancel(notificationId);  // the bit that cancels the notification
        }
        Toast.makeText(getBaseContext(),"Action ID is: "+actionId,
                Toast.LENGTH_SHORT).show();
    }
}
intent.extras?.apply {
            getString("actionId")?.let {
                Log.d("ACTION_ID", it)
                val autoCancel = getBoolean("autoCancel", true)
                val notificationId = getInt("notificationId", -1)

                if (autoCancel && notificationId > -1) {
                    val notifyMgr: NotificationManager =
                        applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                    notifyMgr.cancel(notificationId) // the bit that cancels the notification
                }
                Toast.makeText(baseContext, "Action ID is: $it", Toast.LENGTH_SHORT).show()
            }
        }

The second option is that CleverTap handles closing the notification. You will have to add CleverTap IntentService to your Manifest.xml, and the SDK will do it for you automatically.

<service
    android:name="com.clevertap.android.sdk.pushnotification.CTNotificationIntentService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.clevertap.PUSH_EVENT" />
    </intent-filter>
</service>
996996

Sound Files

You can choose to have no notification sound, the default OS sound, or use a custom sound. It has to be present in the resources folder of your app. refer to the Android sound guide to learn how to add a sound file to your android app. Android only supports .mp3, .ogg and .wav files. Refer to the section Add sound file to your Android app.

Notification Tray Priority

It is the relative priority for this notification in the device tray. Priority indicates how much of the user’s valuable attention must be consumed by this notification.

  • MAXIMUM: Use for critical and urgent notifications that alert the user to a time-critical condition or need to be resolved before continuing with a particular task. A notification with priority set to the maximum will be a heads up notification. It will always be at the top of the notification tray.
  • HIGH: Use primarily for important communication, such as message or chat events with exciting content for the user. High-priority notifications trigger the heads-up notification display. A notification with priority set to high will be a heads up notification.
  • DEFAULT: Use for all notifications that do not fall into any of the other priorities. A notification with default priority will show up in the notification tray, and its order in the notification tray is subject to the presence of other notifications.

📘

Note

Notification tray priority is only applicable for Android 7.1 and below. For Android 8 and above, the notification tray priority is based on the notification channel.

Notification Delivery Priority

You have two options for assigning delivery priority to downstream messages on Android: normal and high priority.

Normal priority - This is the default priority for messages on Android. Normal priority messages are delivered immediately when the app is in the foreground. When the device is in Doze, the delivery may be delayed to conserve battery. For less time-sensitive messages, such as notifications of new email, keeping your UI in sync, or syncing app data in the background, choose normal delivery priority.

High priority - FCM attempts to deliver high priority messages immediately, allowing the FCM service to wake a sleeping device when necessary and to run some limited processing (including very limited network access). High priority messages generally should result in user interaction with your app or its notifications. If FCM detects a pattern in which they don't, your messages may be de-prioritized.

Push Impressions

You can raise and record push notifications delivered onto your users’ Android devices.

  1. Navigate to Settings > Schema > Events.
  2. Search for Push Impressions, then click on the vertical ellipsis.
11611161
  1. Click on Setup push impressions. A new window displays.
  2. Click on Save to enable the option.

If you are custom-handling push notifications, add the following code after you render the push notifications:

CleverTapAPI.getDefaultInstance(this).pushNotificationViewedEvent(extras);
CleverTapAPI.getDefaultInstance([email protected])?.pushNotificationViewedEvent(extras)

Enhanced Push Delivery

Starting with v3.4.0, the SDK supports Enhanced Push Delivery. Enhanced Push Delivery provides the capability to reach users on devices that suppress notifications via GCM/FCM.

To allow your app to use CleverTap's Enhanced Push Delivery via background ping service, add the following fields in your app's AndroidManifest.xml:

<meta-data
    android:name="CLEVERTAP_BACKGROUND_SYNC"
    android:value="1"/>

🚧

Custom Handling

Additional integration is required if the app is rendering push notifications and not the CleverTap SDK. For more information, see custom handling of enhanced push delivery.

Custom Android Push Notification Handling

Step 1. Using Your Custom Implementation
If you have your custom implementation for managing Android push notifications, you can inform CleverTap about the user’s FCM registration ID.

Follow the instructions below if you are using FCM.

String fcmRegId = FirebaseInstanceId.getInstance().getToken();
clevertapDefaultInstance.pushFcmRegistrationId(fcmRegId,true);
val fcmRegId = FirebaseInstanceId.getInstance().token
clevertapDefaultInstance?.pushFcmRegistrationId(fcmRegId, true)

Step 2: Using Multiple Android Push Notification Providers
CleverTap plays well with other Android push notification providers. You can configure your app to work with multiple push notification providers.

If you are using FCM, please follow these instructions.

Subclass FirebaseMessagingService as shown below.

public class MyFcmMessageListenerService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage message){
        try {
            if (message.getData().size() > 0) {
                Bundle extras = new Bundle();
                for (Map.Entry<String, String> entry : message.getData().entrySet()) {
                    extras.putString(entry.getKey(), entry.getValue());
                }

                NotificationInfo info = CleverTapAPI.getNotificationInfo(extras);

                if (info.fromCleverTap) {
                    CleverTapAPI.createNotification(getApplicationContext(), extras);
                } else {
                    // not from CleverTap handle yourself or pass to another provider
                }
            }
        } catch (Throwable t) {
           Log.d("MYFCMLIST", "Error parsing FCM message", t);
        }
    }
}
class MyFcmMessageListenerService : FirebaseMessagingService() {

override fun onMessageReceived(message: RemoteMessage) {

    message.data.apply {
        try {
            if (size > 0) {
                val extras = Bundle()
                for ((key, value) in this) {
                    extras.putString(key, value)
                }
                val info = CleverTapAPI.getNotificationInfo(extras)
                if (info.fromCleverTap) {
                    CleverTapAPI.createNotification(applicationContext, extras)
                } else {
                    // not from CleverTap handle yourself or pass to another provider
                }
            }
        } catch (t: Throwable) {
            Log.d("MYFCMLIST", "Error parsing FCM message", t)
        }
    }
    }
}

From CleverTap Android SDK v4.4.0 onwards you can just write this one line in your own FirebaseMessagingService class instead of the above code

public class MyFcmMessageListenerService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage message){
        CTFcmMessageHandler()
                .createNotification(getApplicationContext(), message);
    }
}
class MyFcmMessageListenerService : FirebaseMessagingService() {

    @Override
    public void onMessageReceived(RemoteMessage message){
        CTFcmMessageHandler()
                .createNotification(applicationContext, message)
    }
}

Add your service to the AndroidManifest.xml in place of the CleverTap FcmMessageListenerService.

<service
    android:name="com.your.package.MyFcmMessageListenerService"
    android:exported="true">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

Replace com.your.package with the correct package name which contains the newly created class, MyFcmMessageListenerService.

To track the push notification events and deeplinks add the following receiver in your AndroidManifest.xml.

<receiver
    android:name="com.clevertap.android.sdk.pushnotification.CTPushNotificationReceiver"
    android:exported="false"
    android:enabled="true">
</receiver>

specify the changes that have happend post 4.3.0
Step 3: Structure of CleverTap FCM Payload

Here is the structure of the payload with a CleverTap FCM push notification.

Key

Type

Description

wzrk_pn

N/A

If present, this notification is sent from CleverTap.

wzrk_id

string

Open rate tracking ID (can be empty or it might not be present).

wzrk_bp

string

If present, the value will be a URL of an image, that needs to be displayed in the notification.

wzrk_sound

boolean or string

If present, it signifies that the default or custom Android notification sound must be played.

nt

string

Notification Title, if absent or empty, fallback to the app name.

nm

string

Notification Body, if absent or empty, ignore this notification.

wzrk_dl

string

If present, this is a deeplink that must be followed at the time of notification open.

wzrk_d

N/A

If present, ignore this notification.

ico

string

If present and not empty, it contains the URL of an image, that must be used as the small notification icon.

wzrk_pivot

string

If present and not empty, it signifies the type of variant in A/B campaigns.

wzrk_rnv

string

If present and not empty, it will raise Push Impressions event

wzrk_nms

string

If present and not empty, it contains the summary text to be displayed along with the image.

wzrk_st

string

If present and not empty, it contains the subtitle text which is displayed next to the App name.

wzrk_clr

string

If present and not empty, it contains the Hex value of the colour to be applied on the small icon (and app name for Android versions below Pie)

If the field nm is empty, ignore the notification. CleverTap sends out a dummy notification with the nm field empty to test for app uninstalls. In addition to the above, attach all keys starting with wzrk_ to your notification extras (For example, wzrk_id is used to track notification opens).

Custom Handling of Enhanced Push Delivery

  1. In your custom FCM Receiver class, add the following code snippet when you receive the RemoteMessage object from Firebase. This method allows you to ensure that duplicate Push notification is not rendered on your device via Enhanced Push Delivery.
if (message.getData().size() > 0) {
                Bundle extras = new Bundle();
                Iterator var = message.getData().entrySet().iterator();

                while(var.hasNext()) {
                    Map.Entry entry = (Map.Entry)var.next();
                    extras.putString((String)entry.getKey(), (String)entry.getValue());
                }
                    CleverTapAPI.processPushNotification(getApplicationContext(),extras);
                }
            }
if (message.getData().size() > 0)
{
  val extras = Bundle()
  val `var` = message.getData().entrySet().iterator()
  while (`var`.hasNext())
  {
    val entry = `var`.next() as Map.Entry
    extras.putString(entry.getKey() as String, entry.getValue() as String)
  }
  CleverTapAPI.processPushNotification(getApplicationContext(), extras)
}
  1. In your Application class, implement the CTPushAmpListener interface.
public class MyApplication extends Application implements CTPushAmpListener {

// your application class code
}
class MyApplication:Application(), CTPushAmpListener// your application class code
  1. In the onCreate() method of your Application class, create an instance of CleverTapAPI and set the CTPushAmpListener as following:
CleverTapAPI cleverTapAPI = CleverTapAPI.getDefaultInstance(getApplicationContext());
cleverTapAPI.setCTPushAmpListener(this);
val cleverTapAPI = CleverTapAPI.getDefaultInstance(getApplicationContext())
cleverTapAPI.setCTPushAmpListener(this)
  1. After the listener is set, whenever a Push Notification is sent to the device via Enhanced Push Delivery, the app will receive the payload in the onPushPayloadReceived method. Implement this method as follows and ensure that your rendering logic of the Push Notification is written here:
@Override
public void onPushPayloadReceived(Bundle bundle) {
    //write push notification rendering logic here
}
fun onPushPayloadReceived(bundle:Bundle) {
  //write push notification rendering logic here
}

Did this page help you?