Segment Native Android Integration

Learn how to integrate Segment with CleverTap in Android.

Overview

Segment Native Android integration allows you to push your Android application data to CleverTap through Segment.

With this integration, you can:

  • Push User Profiles
  • Push Events
  • Integrate Push Notifications

Prerequisites

The following are the prerequisites for performing this integration:

  • A CleverTap account
  • A Segment account
  • A functional Android application

Integration

CleverTap Segment Android integration consists of the following major steps:

  1. Add Destination on Segment Dashboard
  2. Install SDK in the Native Application
  3. Initialize the Segment Client

Add Destination in Segment

Destinations are the business tools or applications to which Segment forwards your data. Adding Destinations allows you to act on your data and learn more about your customers in real-time.

To add CleverTap details in Segment:

  1. Go to Destinations in Segment application.
  2. Click on Add Destination and select CleverTap.
  3. In the Destination Catalog/CleverTap page, click on Configure CleverTap.
  4. Add CleverTap Account ID and Account Token, which you can find on the CleverTap Dashboard under Settings page.
  5. Select the appropriate region from the Region dropdown. To identify the region of your CleverTap account, refer to the following table:
  1. Turn on the toggle at the top of the Settings page to enable the destination.
Enable the CleverTap Settings

Enable the CleverTap Settings

You can integrate CleverTap from the server-side or mobile destination (iOS or Android). Select mobile destinations to use CleverTap push notifications or In-App notifications.

Install SDK in the Native Application

To install Android SDK within the application, add the following dependencies in the app/build.gradle file:

dependencies {

    //segment and clevertap dependencies
    implementation 'com.segment.analytics.android:analytics:4.10.4'
    implementation 'com.clevertap.android:clevertap-android-sdk:4.5.2'
    implementation 'com.clevertap.android:clevertap-segment-android:1.5.0'
    
    //core android dependencies
    implementation 'androidx.core:core:1.3.0'
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'androidx.viewpager:viewpager:1.0.0'
    implementation 'androidx.fragment:fragment:1.3.6'
    implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'


    //google and 3rd party dependencies
    implementation 'com.google.firebase:firebase-messaging:21.0.0'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'com.google.android.exoplayer:exoplayer:2.15.1'//Mandatory if using App Inbox
    implementation 'com.google.android.exoplayer:exoplayer-hls:2.15.1'//Mandatory if using App Inbox
    implementation 'com.google.android.exoplayer:exoplayer-ui:2.15.1'//Mandatory if using App Inbox

    implementation 'com.github.bumptech.glide:glide:4.12.0'//Mandatory if using App Inbox
}
// at the end of the build.gradle file
apply plugin: 'com.google.gms.google-services'

Initialize the Segment Client

To initialize the Segment client:

  1. Add the following code to your Application class file:
public class CleverTapSegmentApplication extends Application {

private static final String TAG = String.format("%s.%s", "CLEVERTAP", CleverTapSegmentApplication.class.getName());
private static final String WRITE_KEY = "<Your_WRITE_KEY>"; //This you will receive under source in segment. 
private static final String CLEVERTAP_KEY = "CleverTap";
public static boolean sCleverTapSegmentEnabled = false;
private CleverTapAPI clevertap;
private static Handler handler = null;

@Override 
public void onCreate() 
{
  super.onCreate();

  CleverTapAPI.setDebugLevel(CleverTapAPI.LogLevel.DEBUG);

  Analytics analytics = new Analytics.Builder(getApplicationContext(), WRITE_KEY)
    .logLevel(Analytics.LogLevel.VERBOSE) 
    .use(CleverTapIntegration.FACTORY) 
    .build();

  analytics.onIntegrationReady(CLEVERTAP_KEY, new Analytics.Callback<CleverTapAPI>() 
  { 
    @Override
    public void onReady(CleverTapAPI instance) {
        Log.i(TAG, "analytics.onIntegrationReady() called");
        cleverTapIntegrationReady(instance); 
      }
    });
  Analytics.setSingletonInstance(analytics); 
}

  private void cleverTapIntegrationReady(CleverTapAPI instance) 
  { 
    instance.enablePersonalization();
    sCleverTapSegmentEnabled = true;
    clevertap = instance;
  } 
}
class CleverTapSegmentApplication: Application() {
    private val TAG = String.format("%s.%s", "CLEVERTAP", CleverTapSegmentApplication::class.java.name)
    private val WRITE_KEY = "<Your_WRITE_KEY>" //This you will receive under source in segment.
    private val CLEVERTAP_KEY = "CleverTap"
    var sCleverTapSegmentEnabled = false
    private var clevertap: CleverTapAPI? = null

    override fun onCreate() {
        super.onCreate()

        CleverTapAPI.setDebugLevel(CleverTapAPI.LogLevel.DEBUG)

        val analytics = Analytics.Builder(applicationContext, WRITE_KEY)
            .logLevel(Analytics.LogLevel.VERBOSE)
            .use(CleverTapIntegration.FACTORY)
            .build()

        analytics.onIntegrationReady<CleverTapAPI>(CLEVERTAP_KEY) { instance ->
            Log.i(TAG, "analytics.onIntegrationReady() called")
            cleverTapIntegrationReady(instance)
        }
        Analytics.setSingletonInstance(analytics)
    }

    private fun cleverTapIntegrationReady(instance: CleverTapAPI) {
        instance.enablePersonalization()
        sCleverTapSegmentEnabled = true
        clevertap = instance
    }
}
ParameterDescription
YOUR_WRITE_KEYFrom the Segment dashboard, navigate to Connections > Sources. Select the source and then navigate to Settings > API Keys to find the Write Key details.
  1. Add the following permissions in the AndroidManifest.xml file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

Push User Information

The onUserLogin method in CleverTap captures multiple user logins or signup on the same device. This method is useful when the user performs a login or sign-up, or wants to push data to CleverTap. Call the identify method in Segment to use the CleverTap onUserLogin method.

Traits traits = new Traits();
traits.putEmail("[email protected]");
traits.putName("FooName");
traits.putPhone("+14155551234"); 
Analytics.with(getApplicationContext()).identify(61026032, traits, null);
//Replace all the example values with your required dynamic ones.
val traits = Traits()
traits.putEmail("[email protected]")
traits.putName("FooName")
traits.putPhone("+14155551234")
Analytics.with(applicationContext).identify(61026032, traits, null)
//Replace all the example values with your required dynamic ones.

Pushing the user information applies only to Segment-CleverTap SDK version v1.1.2 and above.

📘

Update User Property to CleverTap

To update any user property to CleverTap, pass the same user identity passed during the user login or sign-up.

For more details, refer to User Profile Considerations.

Push Events

Events track users' actions in your application. To push events to the CleverTap dashboard, add the following code:

Analytics.with(getApplicationContext()).track("testEvent",
new Properties().putValue("value", "testValue") .putValue("testDate", new Date(System.currentTimeMillis()))
);
Analytics.with(applicationContext).track(
     "testEvent",
      Properties().putValue("value", "testValue").putValue("testDate", Date(System.currentTimeMillis()))
)

Here, testEvent is the Event Name and Value. testDate is the Event Date Property.
For more details, refer to Event Considerations.

Push Charged Events

When an event is tracked using the server-side destination with the name Order Completed(as per e-commerce tracking API), Segment maps that event to CleverTap’s charged event.
To push charged events to the CleverTap dashboard, add the following code:

void raiseChargedEvent(Analytics analytics){
        Properties properties = new  Properties();
        properties.putValue("orderId", "123456");
        properties.putValue("revenue", 100);
        properties.putProducts(
                        new Properties.Product("id1", "sku1", 100.0),
                        new Properties.Product("id2", "sku2", 200.0)
                );
        analytics.track("Order Completed", properties);
    }
fun raiseChargedEvent(analytics: Analytics) {
        val properties = Properties()
        properties.putValue("orderId", "123456")
        properties.putValue("revenue", 100)
        properties.putProducts(
            Product("id1", "sku1", 100.0),
            Product("id2", "sku2", 200.0)
        )
        analytics.track("Order Completed", properties)
    }

It appears as a charged event on the CleverTap dashboard, as shown in the following figure:

2742

Charged Event on CleverTap Dashboard

Integrate Push Notifications

Case 1: When you are using push notifications only from CleverTap.
Add the following code to your AndroidManifest.xml file:

<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>

<meta-data
android:name="CLEVERTAP_NOTIFICATION_ICON" 
android:value="ic_stat_red_star"/>

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

Case 2: When you send Push from different tools, such as Firebase.
To enable this, perform the following steps:

  1. Add the following code to your AndroidManifest.xml file:
<meta-data
  android:name="CLEVERTAP_NOTIFICATION_ICON" 
  android:value="ic_stat_red_star"/>
<!—Above meta data is optional -->

<service android:name="com.clevertap.android.sdk.CTNotificationIntentService" >
  <intent-filter>
    <action android:name="com.clevertap.PUSH_EVENT"/> 
  </intent-filter>
</service>
  1. Add the following code to your onNewToken method:

📘

Note

Use the onTokenRefresh method only if your firebase message delivery system version is 18.0 and above.

String fcmRegId = FirebaseInstanceId.getInstance().getToken(); 
clevertapDefaultInstance.pushFcmRegistrationId(fcmRegId,true);
val fcmRegId = FirebaseInstanceId.getInstance().token
clevertapDefaultInstance?.pushFcmRegistrationId(fcmRegId, true)
  1. Add the following code in your MyFcmMessageListenerService class file.
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) {
        super.onMessageReceived(message)
        try {
            if (message.data.isNotEmpty()) {
                val extras = Bundle()
                for (entry: Map.Entry<String?, String?> in message.data) {
                    extras.putString(entry.key, entry.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)
        }
    }
}
  1. Add the following code to create a Notification Channel for Android O and above:
CleverTapAPI.createNotificationChannel(getApplicationContext(),"YourChannelId","Your Channel Name","Your Channel Description",NotificationManager.IMPORTANCE_MAX,true);
CleverTapAPI.createNotificationChannel(applicationContext, "YourChannelId", "Your Channel Name", "Your Channel Description", NotificationManager.IMPORTANCE_MAX, true)

Integrate In-App in Android

All the required methods are available out of the box in the Segment-CleverTap SDK.
For more information about integrating In-App in Android, refer to Android In-App.

Integrate App Inbox in Android

App Inbox allows you to send permanent content directly to your application from the CleverTap dashboard. Moreover, the inbox messages target individual segments such as other messaging channels. Your inbox can look different from another user's inbox; the possibilities are endless.

Add the following code to initialize the App Inbox and register callbacks:

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.clevertap.android.sdk.CTInboxListener;
import com.clevertap.android.sdk.CTInboxStyleConfig;
import com.clevertap.android.sdk.CleverTapAPI;
import com.segment.analytics.Analytics;
import com.segment.analytics.android.integrations.clevertap.CleverTapIntegration;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements CTInboxListener {

    private CleverTapAPI ctApiGlobalInstance = null;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        new Analytics
                .Builder(getApplicationContext(),SOURCE_ANDROID_KEY)
                .use(CleverTapIntegration.FACTORY)
                .build()
                .onIntegrationReady(
                        "CleverTap",
                        (Analytics.Callback<CleverTapAPI>) ctApi -> {
                            // set instance as global for future use
                            ctApiGlobalInstance = ctApi;

                            //Set the Notification Inbox Listener
                            ctApiGlobalInstance.setCTNotificationInboxListener(this);

                            //Initialize the inbox and wait for callbacks on overridden methods
                            ctApiGlobalInstance.initializeInbox();

                        }
                );
    }
    @Override
    public void inboxDidInitialize() {
        // add an on click to your inbox button to call showAppInbox() with custom or default styling
        yourInboxButton.setOnClickListener(v -> {
            ArrayList<String> tabs = new ArrayList<>();
            tabs.add("Promotions");
            tabs.add("Offers");//We support upto 2 tabs only. Additional tabs will be ignored

            CTInboxStyleConfig styleConfig = new CTInboxStyleConfig();
            styleConfig.setFirstTabTitle("First Tab");
            styleConfig.setTabs(tabs);//Do not use this if you don't want to use tabs
            styleConfig.setTabBackgroundColor("#FF0000");
            styleConfig.setSelectedTabIndicatorColor("#0000FF");
            styleConfig.setSelectedTabColor("#0000FF");
            styleConfig.setUnselectedTabColor("#FFFFFF");
            styleConfig.setBackButtonColor("#FF0000");
            styleConfig.setNavBarTitleColor("#FF0000");
            styleConfig.setNavBarTitle("MY INBOX");
            styleConfig.setNavBarColor("#FFFFFF");
            styleConfig.setInboxBackgroundColor("#ADD8E6");
            if (ctApiGlobalInstance != null) {
                ctApiGlobalInstance.showAppInbox(styleConfig); //With Tabs
                //ctApiGlobalInstance.showAppInbox();//Opens Activity with default style configs
            }
        });
    }
    @Override
    public void inboxMessagesDidUpdate() {
        //Callback on Inbox Message update/delete/read (any activity)
    }
}
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.clevertap.android.sdk.CTInboxListener
import com.clevertap.android.sdk.CTInboxStyleConfig
import com.clevertap.android.sdk.CleverTapAPI
import com.segment.analytics.Analytics
import com.segment.analytics.android.integrations.clevertap.CleverTapIntegration

import java.util.ArrayList


class MainActivity : AppCompatActivity(), CTInboxListener {
    private var ctApiGlobalInstance: CleverTapAPI? = null

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

        Analytics.Builder(applicationContext, SOURCE_ANDROID_KEY)
            .use(CleverTapIntegration.FACTORY)
            .build()
            .onIntegrationReady(
                "CleverTap",
                Analytics.Callback { ctApi: CleverTapAPI ->
                    // set instance as global for future use
                    ctApiGlobalInstance = ctApi

                    //Set the Notification Inbox Listener
                    ctApiGlobalInstance?.ctNotificationInboxListener = this

                    //Initialize the inbox and wait for callbacks on overridden methods
                    ctApiGlobalInstance?.initializeInbox()
                } as Analytics.Callback<CleverTapAPI>
            )
    }

    override fun inboxDidInitialize() {
        // add an on click to your inbox button to call showAppInbox() with custom or default styling
        yourInboxButton.setOnClickListener { v ->
            val tabs: ArrayList<String> = ArrayList()
            tabs.add("Promotions")
            tabs.add("Offers") //We support upto 2 tabs only. Additional tabs will be ignored
            val styleConfig = CTInboxStyleConfig()
            styleConfig.firstTabTitle = "First Tab"
            styleConfig.tabs = tabs //Do not use this if you don't want to use tabs
            styleConfig.tabBackgroundColor = "#FF0000"
            styleConfig.selectedTabIndicatorColor = "#0000FF"
            styleConfig.selectedTabColor = "#0000FF"
            styleConfig.unselectedTabColor = "#FFFFFF"
            styleConfig.backButtonColor = "#FF0000"
            styleConfig.navBarTitleColor = "#FF0000"
            styleConfig.navBarTitle = "MY INBOX"
            styleConfig.navBarColor = "#FFFFFF"
            styleConfig.inboxBackgroundColor = "#ADD8E6"
            if (ctApiGlobalInstance != null) {
                ctApiGlobalInstance!!.showAppInbox(styleConfig) //With Tabs
                //ctApiGlobalInstance.showAppInbox();//Opens Activity with default style configs
            }
        }
    }

    override fun inboxMessagesDidUpdate() {
        //Callback on Inbox Message update/delete/read (any activity)
    }
}

For additional methods and App Inbox features, refer to the App Inbox for Android.

Integrate Native Display in Android

CleverTap supports Native Display for CleverTap Android SDK version 3.6.2 and above.
To integrate Native Display with your application:

  1. Add the following code to register the Native Display Listener and get the NativeDisplayUnits using the setDisplayUnitListener method:
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.clevertap.android.sdk.CleverTapAPI;
import com.clevertap.android.sdk.displayunits.DisplayUnitListener;
import com.clevertap.android.sdk.displayunits.model.CleverTapDisplayUnit;
import com.segment.analytics.Analytics;
import com.segment.analytics.android.integrations.clevertap.CleverTapIntegration;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements DisplayUnitListener {

    private CleverTapAPI ctApiGlobalInstance = null;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        new Analytics
                .Builder(getApplicationContext(),SOURCE_ANDROID_KEY)
                .use(CleverTapIntegration.FACTORY)
                .build()
                .onIntegrationReady(
                        "CleverTap",
                        (Analytics.Callback<CleverTapAPI>) ctApi -> {
                            // set instance as global for future use
                            ctApiGlobalInstance = ctApi;

                            //set display unit listener
                            ctApiGlobalInstance.setDisplayUnitListener(this);

                           

                            // We have also provided a few utility methods to get Adunits corresponding to the last event raised.
                            ctApiGlobalInstance.getAllDisplayUnits();
                        }
                );
    }
    @Override
    public void onDisplayUnitsLoaded(ArrayList<CleverTapDisplayUnit> units) {
        // you will get display units here
        // implement your logic to create your display views using these Display Units here
        for (int i = 0; i <units.size() ; i++) {
            CleverTapDisplayUnit unit = units.get(i);
            prepareDisplayView(unit); //your function to create display unit
        }
    }
}
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.clevertap.android.sdk.CleverTapAPI
import com.clevertap.android.sdk.displayunits.DisplayUnitListener
import com.clevertap.android.sdk.displayunits.model.CleverTapDisplayUnit
import com.segment.analytics.Analytics
import com.segment.analytics.android.integrations.clevertap.CleverTapIntegration

class MainActivity : AppCompatActivity(), DisplayUnitListener {
    private var ctApiGlobalInstance: CleverTapAPI? = null

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

        Analytics.Builder(applicationContext, SOURCE_ANDROID_KEY)
            .use(CleverTapIntegration.FACTORY)
            .build()
            .onIntegrationReady(
                "CleverTap",
                Analytics.Callback { ctApi: CleverTapAPI ->
                    // set instance as global for future use
                    ctApiGlobalInstance = ctApi

                    //set display unit listener
                    ctApiGlobalInstance?.setDisplayUnitListener(this)

                    // We have also provided a few utility methods to get Adunits corresponding to the last event raised.
                    ctApiGlobalInstance?.allDisplayUnits
                } as Analytics.Callback<CleverTapAPI>
            )
    }

    override fun onDisplayUnitsLoaded(units: ArrayList<CleverTapDisplayUnit>?) {
        // you will get display units here
        // implement your logic to create your display views using these Display Units here
        for (i in 0 until units!!.size) {
            val unit = units[i]
            prepareDisplayView(unit) //your function to create display unit
        }
    }
}

Once the campaign for native display is triggered, you will receive the list of CleverTapDisplayUnit via the registered callback for all active Native Display campaigns. This CleverTapDisplayUnit is used to create Native Display views.

  1. Add the following code to raise the user event for the Native Display campaign:
ctApiGlobalInstance.pushEvent("Your Event Name");
ctApiGlobalInstance?.pushEvent("Your Event Name")

For additional methods and Native Display features, refer to Native Display for Android.

Advanced Features

To add advanced features to your Android application, refer to Android Advanced Settings.