Skip to content

AppsFlyerSDK/appsflyer-segment-android-plugin

Repository files navigation

AppsFlyer - Segment Integration

CI - Tests Maven Central


In order for us to provide optimal support, we would kindly ask you to submit any issues to support@appsflyer.com

When submitting an issue please specify your AppsFlyer sign-up (account) email , your app ID , production steps, logs, code snippets and any additional relevant information.

Overview

AppsFlyer SDK provides app installation and event tracking functionality. We have developed an SDK that is highly robust (7+ billion SDK installations to date), secure, lightweight and very simple to embed.

You can track installs, updates and sessions and also track additional in-app events beyond app installs (including in-app purchases, game levels, etc.) to evaluate ROI and user engagement levels.


Built with AppsFlyer Android SDK v6.13.0

Table of content

Introduction

Segment makes it easy to send your data to AppsFlyer. Once you have tracked your data through Segment's open source libraries, the data is translated and routed to AppsFlyer in the appropriate format. AppsFlyer helps marketers to pinpoint targeting, optimize ad spend and boost ROI.

The AppsFlyer integration code is open-source on GitHub if you want to check it out.

Check out the Segment AppsFlyer docs here.

Getting Started

DashBoard Setup

To enable AppsFlyer in the Segment dashboard, follow these steps:

  1. Enter your unique AppsFlyer Dev Key, which is accessible from your AppsFlyer account, in Segment’s destination settings.
  2. After you build and release to the app store, your data is translated and sent to AppsFlyer automatically.

The Segment AppsFlyer integration is entirely handled through Segment's servers, so you don’t need to bundle AppsFlyer's iOS or Android SDKs. Your Segment SDK will be enough.

AppsFlyer supports the identify and track methods.

Manual mode

Starting version 6.8.0, we support a manual mode to seperate the initialization of the AppsFlyer SDK and the start of the SDK. In this case, the AppsFlyer SDK won't start automatically, giving the developper more freedom when to start the AppsFlyer SDK. Please note that in manual mode, the developper is required to implement the API startAppsFlyer(Context context) in order to start the SDK.
If you are using CMP to collect consent data this feature is needed. See explanation here.

Example:

AppsflyerIntegration.setManualMode(true);

And to start the AppsFlyer SDK, use void startAppsFlyer(Context context) API.

Example:

    protected void onCreate(Bundle savedInstanceState) {
         AppsflyerIntegration.startAppsFlyer(this);
    }

Setting up the SDK

2.1) Adding the Plugin to your Project

Add the AppsFlyer Segment Integration dependency to your app build.gradle file.

implementation 'com.appsflyer:segment-android-integration:6.13.0'
implementation 'com.android.installreferrer:installreferrer:2.1'

2.2) Setting the Required Permissions

The AndroidManifest.xml should include the following permissions:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

In v6.8.0 of the AppsFlyer SDK, we added the normal permission com.google.android.gms.permission.AD_ID to the SDK's AndroidManifest, to allow the SDK to collect the Android Advertising ID on apps targeting API 33. If your app is targeting children, you may need to revoke this permission to comply with Google's Data policy. You can read more about it here.

static final String SEGMENT_WRITE_KEY = "<YOUR_KEY>";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Analytics.Builder builder = new Analytics.Builder(this , SEGMENT_WRITE_KEY)
.use(AppsflyerIntegration.FACTORY)

...
(optional)

.logLevel(Analytics.LogLevel.VERBOSE)
.recordScreenViews()
.trackApplicationLifecycleEvents() // Application Opened , Application Updated , Application Installed events
.build();

Analytics.setSingletonInstance(builder.build());

}

Adding .trackApplicationLifecycleEvents() will send Application Opened , Application Updated and Application Installed events to AppsFlyer.

When you call track, Segment translates it automatically and sends the event to AppsFlyer.

Segment includes all the event properties as callback parameters on the AppsFlyer event, and automatically translates properties.revenue to the appropriate AppsFlyer purchase event properties based on Segment's spec’d properties.

Finally, Segment automatically uses AppsFlyer’s transactionId-based de-duplication when sending an an orderId.

Purchase Event Example:

Map<String, Object> eventValue = new HashMap<String, Object>();
eventValue.put("productId","com.test.id");
eventValue.put("revenue","1.00");
eventValue.put("currency","USD");

Analytics analytics = Analytics.with(this);
Properties properties = new Properties();
properties.putAll(eventValue);

analytics.track("purchase", properties);

Note: AppsFlyer will map revenue -> af_revenue and currency -> af_currency.

Check out the Segment docs on track here.

Identify

When you identify a user, that user’s information is passed to AppsFlyer with customer user Id as AppsFlyer’s External User ID. Segment’s special traits recognized as AppsFlyer’s standard user profile fields (in parentheses) are:

customerUserId (Customer User Id)
currencyCode (Currency Code)

All other traits will be sent to AppsFlyer as custom attributes.

Analytics analytics = Analytics.with(this);

analytics.identify("a user's id", new Traits()
.putName("a user's name")
.putEmail("maxim@appsflyer.com"),
null);

Check out the Segment docs on indentify here.

Get Conversion Data

For Conversion data your should call the method below.

         AppsflyerIntegration.conversionListener  = new AppsflyerIntegration.ExternalAppsFlyerConversionListener() {
                    @Override
                    public void onConversionDataSuccess(Map<String, Object> map) {
                        // Process Deferred Deep Linking here
                        for (String attrName : map.keySet()) {
                            Log.d(TAG, "attribute: " + attrName + " = " + map.get(attrName));
                        }
                    }

                    @Override
                    public void onConversionDataFail(String s) {

                    }

                    @Override
                    public void onAppOpenAttribution(Map<String, String> map) {
                     // Process Direct Deep Linking here
                        for (String attrName : map.keySet()) {
                            Log.d(TAG, "attribute: " + attrName + " = " + map.get(attrName));
                        }
                    }

                    @Override
                    public void onAttributionFailure(String s) {

                    }
                };

In order for Conversion Data to be sent to Segment, make sure you have enabled "Track Attribution Data" in AppsFlyer destination settings:

Xnip2019-05-11_19-19-31

Unified deep linking

In order to implement unified deep linking, call the method below :

        AppsflyerIntegration.deepLinkListener = new AppsflyerIntegration.ExternalDeepLinkListener() {
            @Override
            public void onDeepLinking(@NonNull DeepLinkResult deepLinkResult) {
                //TODO handle deep link logic
            }
        };

For more information about unified deep linking, check here

For a general introduction to DMA consent data, see here. The SDK offers two alternative methods for gathering consent data:

  • Through a Consent Management Platform (CMP): If the app uses a CMP that complies with the Transparency and Consent Framework (TCF) v2.2 protocol, the SDK can automatically retrieve the consent details.

    OR

  • Through a dedicated SDK API: Developers can pass Google's required consent data directly to the SDK using a specific API designed for this purpose.

Use CMP to collect consent data

A CMP compatible with TCF v2.2 collects DMA consent data and stores it in SharedPreferences. To enable the SDK to access this data and include it with every event, follow these steps:

  1. Call AppsFlyerLib.getInstance().enableTCFDataCollection(true) to instruct the SDK to collect the TCF data from the device.
  2. Set the the adapter to be manual : AppsflyerIntegration.setManualMode(true).
    This will allow us to delay the Conversion call in order to provide the SDK with the user consent.
  3. Initialize Segment using AppsflyerIntegration.FACTORY.
  4. In the Activity class, use the CMP to decide if you need the consent dialog in the current session.
  5. If needed, show the consent dialog, using the CMP, to capture the user consent decision. Otherwise, go to step 6.
  6. Get confirmation from the CMP that the user has made their consent decision, and the data is available in SharedPreferences.
  7. Call AppsflyerIntegration.startAppsFlyer(this)

Application class

@Override public void onCreate() {
    super.onCreate();
    AppsFlyerLib.getInstance().enableTCFDataCollection(true);
    AppsflyerIntegration.setManualMode(true);
    initSegmentAnalytics();
}

private void initSegmentAnalytics() {
    Analytics.Builder builder = new Analytics.Builder(this, SEGMENT_WRITE_KEY)
            .use(AppsflyerIntegration.FACTORY)
            .logLevel(Analytics.LogLevel.VERBOSE)
            .trackApplicationLifecycleEvents() // Enable this to record certain application events automatically!
            .recordScreenViews(); // Enable this to record screen views automatically!
    // Set the initialized instance as a globally accessible instance.
    Analytics.setSingletonInstance(builder.build());
}

Activity class

public class MainActivity extends AppCompatActivity {

  private boolean consentRequired = true;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      if (consentRequired)
          initConsentCollection();
      else
          AppsflyerIntegration.startAppsFlyer(this);
  }
  
  private void initConsentCollection() {
    // Implement here the you CMP flow
    // When the flow is completed and consent was collected 
    // call onConsentCollectionFinished()
  }

  private void onConsentCollectionFinished() {
    AppsflyerIntegration.startAppsFlyer(this);
  }
}

Manually collect consent data

If your app does not use a CMP compatible with TCF v2.2, use the SDK API detailed below to provide the consent data directly to the SDK.

  1. Initialize AppsFlyerIntegration using manual mode and also Analytics. This will allow us to delay the Conversion call in order to provide the SDK with the user consent.
  2. In the Activity class, determine whether the GDPR applies or not to the user.
    - If GDPR applies to the user, perform the following:
    1. Given that GDPR is applicable to the user, determine whether the consent data is already stored for this session.
      1. If there is no consent data stored, show the consent dialog to capture the user consent decision.
      2. If there is consent data stored continue to the next step.
    2. To transfer the consent data to the SDK create an object called AppsFlyerConsent using the forGDPRUser() method with the following parameters:
      - hasConsentForDataUsage - Indicates whether the user has consented to use their data for advertising purposes.
      - hasConsentForAdsPersonalization - Indicates whether the user has consented to use their data for personalized advertising purposes.
    3. Call AppsFlyerLib.getInstance().setConsentData() with the AppsFlyerConsent object.
    4. Call AppsflyerIntegration.startAppsFlyer(this).

    - If GDPR doesn’t apply to the user perform the following:
    1. Create an AppsFlyerConsent object using the forNonGDPRUser() method. This method doesn’t accept any parameters.
    2. Call AppsFlyerLib.getInstance().setConsentData() with the AppsFlyerConsent object.
    3. Call AppsflyerIntegration.startAppsFlyer(this).

Sample App

AppsFlyer has created a sample Android application that integrates AppsFlyer via Segment. Check it out at the Github repo.