{"id":21478234,"url":"https://github.com/appsflyersdk/appsflyer-segment-android-plugin","last_synced_at":"2025-08-21T11:32:49.437Z","repository":{"id":44702939,"uuid":"57197626","full_name":"AppsFlyerSDK/appsflyer-segment-android-plugin","owner":"AppsFlyerSDK","description":"AppsFlyer's Android SDK - Segment Integration","archived":false,"fork":false,"pushed_at":"2024-09-02T10:39:01.000Z","size":435,"stargazers_count":27,"open_issues_count":1,"forks_count":26,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-12-06T21:27:03.536Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AppsFlyerSDK.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-27T08:36:24.000Z","updated_at":"2024-08-07T13:30:29.000Z","dependencies_parsed_at":"2024-05-02T07:47:28.068Z","dependency_job_id":null,"html_url":"https://github.com/AppsFlyerSDK/appsflyer-segment-android-plugin","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fappsflyer-segment-android-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fappsflyer-segment-android-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fappsflyer-segment-android-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fappsflyer-segment-android-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AppsFlyerSDK","download_url":"https://codeload.github.com/AppsFlyerSDK/appsflyer-segment-android-plugin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230511479,"owners_count":18237657,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-23T11:17:23.548Z","updated_at":"2025-08-21T11:32:49.431Z","avatar_url":"https://github.com/AppsFlyerSDK.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://massets.appsflyer.com/wp-content/uploads/2018/06/20092440/static-ziv_1TP.png\"  width=\"400\" \u003e \n\n\n# AppsFlyer - Segment Integration\n[![CI - Tests](https://github.com/AppsFlyerSDK/appsflyer-segment-android-plugin/actions/workflows/unit-tests-workflow.yml/badge.svg)](https://github.com/AppsFlyerSDK/appsflyer-segment-android-plugin/actions/workflows/unit-tests-workflow.yml)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.appsflyer/segment-android-integration/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.appsflyer/segment-android-integration)\n\n----------\nIn order for us to provide optimal support, we would kindly ask you to submit any issues to support@appsflyer.com\n\n*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.*\n\n\n# Overview\n\nAppsFlyer 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.\n\n\n\nYou 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.\n\n---\n\nBuilt with AppsFlyer Android SDK `v6.17.1`\n\n## Table of content\n\n- [Introduction](#whatIsSegment)\n- [Getting Started](#quickStart)\n- [Manual mode](#manual)\n-  [SDK Initialization](#sdk_init)\n-  [Register In-App Events](#adding_events)\n-  [Get Conversion Data](#conversion_data)\n- [Unified Deep Linking](#deep_linking)\n- [Send consent for DMA compliance](#dma_support) \n- [Sample App](#sample_app)\n\n\n### \u003ca id=\"whatIsSegment\"\u003e\n# Introduction\n\nSegment 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.\n\n\nThe AppsFlyer integration code is open-source on GitHub if you want to [check it out](https://github.com/segment-integrations/integration-appsflyer).\n\nCheck out the Segment AppsFlyer docs [here](https://segment.com/docs/destinations/appsflyer/).\n\n\n\n\n\n\n### \u003ca id=\"gettingStarted\"\u003e\n# Getting Started\n\n\n#### DashBoard Setup\n\nTo enable AppsFlyer in the Segment dashboard, follow these steps:\n\n1.  Enter your unique AppsFlyer Dev Key, which is accessible from your AppsFlyer account, in Segment’s destination settings.\n2.  After you build and release to the app store, your data is translated and sent to AppsFlyer automatically.\n\n\n\nThe 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.\n\nAppsFlyer supports the `identify` and `track` methods.\n\n### \u003ca id=\"manual\"\u003e\n# Manual mode\nStarting 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.\n\u003cbr\u003eIf you are using CMP to collect consent data this feature is needed. See explanation [here](#dma_support).\n### Example:\n\n```java\nAppsflyerIntegration.setManualMode(true);\n```\n\nAnd to start the AppsFlyer SDK, use `void startAppsFlyer(Context context)` API.\n\n### Example:\n\n```java\n    protected void onCreate(Bundle savedInstanceState) {\n         AppsflyerIntegration.startAppsFlyer(this);\n    }\n ```\n\n\n### \u003ca id=\"quickStart\"\u003e\n\n# Setting up the SDK\n\n#### 2.1) Adding the Plugin to your Project\n\nAdd the AppsFlyer Segment Integration dependency to your app `build.gradle` file.\n```java\nimplementation 'com.appsflyer:segment-android-integration:6.17.1'\nimplementation 'com.android.installreferrer:installreferrer:2.1'\n```\n\n#### 2.2)  Setting the Required Permissions\n\nThe AndroidManifest.xml should include the following permissions:\n\n```xml\n\u003cuses-permission android:name=\"android.permission.INTERNET\" /\u003e\n\u003cuses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" /\u003e\n\u003cuses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" /\u003e\n```\n\nIn v6.8.0 of the AppsFlyer SDK, we added the normal permission com.google.android.gms.permission.AD_ID to the SDK's AndroidManifest, \nto allow the SDK to collect the Android Advertising ID on apps targeting API 33.\nIf your app is targeting children, you may need to revoke this permission to comply with Google's Data policy.\nYou can read more about it [here](https://support.appsflyer.com/hc/en-us/articles/7569900844689).\n\nStarting from **6.14.0** Huawei Referrer integration was updated. [Learn more](https://dev.appsflyer.com/hc/docs/install-android-sdk#huawei-install-referrer).\n\n### \u003ca id=\"sdk_init\"\u003e 2.2)  Init AppsFlyer\n\n```java\n\nstatic final String SEGMENT_WRITE_KEY = \"\u003cYOUR_KEY\u003e\";\n\n@Override\nprotected void onCreate(Bundle savedInstanceState) {\nsuper.onCreate(savedInstanceState);\nsetContentView(R.layout.activity_main);\n\nAnalytics.Builder builder = new Analytics.Builder(this , SEGMENT_WRITE_KEY)\n.use(AppsflyerIntegration.FACTORY)\n\n...\n(optional)\n\n.logLevel(Analytics.LogLevel.VERBOSE)\n.recordScreenViews()\n.trackApplicationLifecycleEvents() // Application Opened , Application Updated , Application Installed events\n.build();\n\nAnalytics.setSingletonInstance(builder.build());\n\n}\n```\n\nAdding `.trackApplicationLifecycleEvents()` will send   `Application Opened`  , `Application Updated`  and `Application Installed` events to AppsFlyer.\n\n\n\n\n## \u003ca id=\"adding_events\"\u003e In-app events\n\nWhen you call `track`, Segment translates it automatically and sends the event to AppsFlyer.\n\nSegment 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.\n\nFinally, Segment automatically uses AppsFlyer’s transactionId-based de-duplication when sending an an `orderId`.\n\n\nPurchase Event Example:\n```java\nMap\u003cString, Object\u003e eventValue = new HashMap\u003cString, Object\u003e();\neventValue.put(\"productId\",\"com.test.id\");\neventValue.put(\"revenue\",\"1.00\");\neventValue.put(\"currency\",\"USD\");\n\nAnalytics analytics = Analytics.with(this);\nProperties properties = new Properties();\nproperties.putAll(eventValue);\n\nanalytics.track(\"purchase\", properties);\n```\n\nNote: AppsFlyer will map `revenue -\u003e af_revenue` and `currency -\u003e af_currency`.\n\nCheck out the Segment docs on track [here](https://segment.com/docs/spec/track/).\n\n\n### \u003ca id=\"identify\"\u003e\n\n## Identify\n\n\nWhen 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:\n\n`customerUserId` (`Customer User Id`) \u003cbr\u003e\n`currencyCode` (`Currency Code`)\n\nAll other traits will be sent to AppsFlyer as custom attributes.\n\n```java\nAnalytics analytics = Analytics.with(this);\n\nanalytics.identify(\"a user's id\", new Traits()\n.putName(\"a user's name\")\n.putEmail(\"maxim@appsflyer.com\"),\nnull);\n```\n\nCheck out the Segment docs on indentify [here](https://segment.com/docs/spec/identify/).\n\n### \u003ca id=\"conversion_data\"\u003e\n\n##  Get Conversion Data\n\nFor Conversion data your should call the method below.\n\n```java\n         AppsflyerIntegration.conversionListener  = new AppsflyerIntegration.ExternalAppsFlyerConversionListener() {\n                    @Override\n                    public void onConversionDataSuccess(Map\u003cString, Object\u003e map) {\n                        // Process Deferred Deep Linking here\n                        for (String attrName : map.keySet()) {\n                            Log.d(TAG, \"attribute: \" + attrName + \" = \" + map.get(attrName));\n                        }\n                    }\n\n                    @Override\n                    public void onConversionDataFail(String s) {\n\n                    }\n\n                    @Override\n                    public void onAppOpenAttribution(Map\u003cString, String\u003e map) {\n                     // Process Direct Deep Linking here\n                        for (String attrName : map.keySet()) {\n                            Log.d(TAG, \"attribute: \" + attrName + \" = \" + map.get(attrName));\n                        }\n                    }\n\n                    @Override\n                    public void onAttributionFailure(String s) {\n\n                    }\n                };\n```\n\nIn order for Conversion Data to be sent to Segment, make sure you have enabled \"Track Attribution Data\" in AppsFlyer destination settings:\n\n\u003cimg width=\"741\" alt=\"Xnip2019-05-11_19-19-31\" src=\"https://user-images.githubusercontent.com/18286267/57572409-8fb19200-7422-11e9-832f-fdd343af3137.png\"\u003e\n\n### \u003ca id=\"deep_linking\"\u003e\n\n##  Unified deep linking\nIn order to implement unified deep linking, call the method below :\n\n```java\n        AppsflyerIntegration.deepLinkListener = new AppsflyerIntegration.ExternalDeepLinkListener() {\n            @Override\n            public void onDeepLinking(@NonNull DeepLinkResult deepLinkResult) {\n                //TODO handle deep link logic\n            }\n        };\n```\nFor more information about unified deep linking, check [here](https://dev.appsflyer.com/docs/android-unified-deep-linking)\n\n## \u003ca id=\"dma_support\"\u003e Send consent for DMA compliance \nFor a general introduction to DMA consent data, see [here](https://dev.appsflyer.com/hc/docs/send-consent-for-dma-compliance).\u003cbe\u003e \nThe SDK offers two alternative methods for gathering consent data:\u003cbr\u003e \n- **Through a Consent Management Platform (CMP)**: If the app uses a CMP that complies with the [Transparency and Consent Framework (TCF) v2.2 protocol](https://iabeurope.eu/tcf-supporting-resources/), the SDK can automatically retrieve the consent details.\u003cbr\u003e \n\u003cbr\u003eOR\u003cbr\u003e\u003cbr\u003e \n- **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. \n### Use CMP to collect consent data \nA CMP compatible with TCF v2.2 collects DMA consent data and stores it in \u003ccode\u003eSharedPreferences\u003c/code\u003e. To enable the SDK to access this data and include it with every event, follow these steps:\u003cbr\u003e \n\u003col\u003e \n  \u003cli\u003e Call \u003ccode\u003eAppsFlyerLib.getInstance().enableTCFDataCollection(true)\u003c/code\u003e to instruct the SDK to collect the TCF data from the device. \n  \u003cli\u003e Set the the adapter to be manual : \u003ccode\u003eAppsflyerIntegration.setManualMode(true)\u003c/code\u003e. \u003cbr\u003e This will allow us to delay the Conversion call in order to provide the SDK with the user consent. \n  \u003cli\u003e Initialize Segment using \u003ccode\u003eAppsflyerIntegration.FACTORY\u003c/code\u003e. \n  \u003cli\u003e In the \u003ccode\u003eActivity\u003c/code\u003e class, use the CMP to decide if you need the consent dialog in the current session.\n  \u003cli\u003e If needed, show the consent dialog, using the CMP, to capture the user consent decision. Otherwise, go to step 6. \n  \u003cli\u003e Get confirmation from the CMP that the user has made their consent decision, and the data is available in \u003ccode\u003eSharedPreferences\u003c/code\u003e.\n  \u003cli\u003e Call \u003ccode\u003eAppsflyerIntegration.startAppsFlyer(this)\u003c/code\u003e\n\u003c/ol\u003e \n \n #### Application class\n``` kotlin\n@Override public void onCreate() {\n    super.onCreate();\n    AppsFlyerLib.getInstance().enableTCFDataCollection(true);\n    AppsflyerIntegration.setManualMode(true);\n    initSegmentAnalytics();\n}\n\nprivate void initSegmentAnalytics() {\n    Analytics.Builder builder = new Analytics.Builder(this, SEGMENT_WRITE_KEY)\n            .use(AppsflyerIntegration.FACTORY)\n            .logLevel(Analytics.LogLevel.VERBOSE)\n            .trackApplicationLifecycleEvents() // Enable this to record certain application events automatically!\n            .recordScreenViews(); // Enable this to record screen views automatically!\n    // Set the initialized instance as a globally accessible instance.\n    Analytics.setSingletonInstance(builder.build());\n}\n``` \n#### Activity class\n```kotlin\npublic class MainActivity extends AppCompatActivity {\n\n  private boolean consentRequired = true;\n  @Override\n  protected void onCreate(Bundle savedInstanceState) {\n      super.onCreate(savedInstanceState);\n      setContentView(R.layout.activity_main);\n      if (consentRequired)\n          initConsentCollection();\n      else\n          AppsflyerIntegration.startAppsFlyer(this);\n  }\n  \n  private void initConsentCollection() {\n    // Implement here the you CMP flow\n    // When the flow is completed and consent was collected \n    // call onConsentCollectionFinished()\n  }\n\n  private void onConsentCollectionFinished() {\n    AppsflyerIntegration.startAppsFlyer(this);\n  }\n}\n```\n\n \n### Manually collect consent data \nIf 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. \n\u003col\u003e \n  \u003cli\u003e Initialize \u003ccode\u003eAppsFlyerIntegration\u003c/code\u003e using manual mode and also \u003ccode\u003eAnalytics\u003c/code\u003e. This will allow us to delay the Conversion call in order to provide the SDK with the user consent. \n  \u003cli\u003e In the \u003ccode\u003eActivity\u003c/code\u003e class, determine whether the GDPR applies or not to the user.\u003cbr\u003e \n  - If GDPR applies to the user, perform the following:  \n      \u003col\u003e \n        \u003cli\u003e Given that GDPR is applicable to the user, determine whether the consent data is already stored for this session. \n            \u003col\u003e \n              \u003cli\u003e If there is no consent data stored, show the consent dialog to capture the user consent decision. \n              \u003cli\u003e If there is consent data stored continue to the next step. \n            \u003c/ol\u003e \n        \u003cli\u003e To transfer the consent data to the SDK create an object called \u003ccode\u003eAppsFlyerConsent\u003c/code\u003e using the \u003ccode\u003eforGDPRUser()\u003c/code\u003e method with the following parameters:\u003cbr\u003e \n          - \u003ccode\u003ehasConsentForDataUsage\u003c/code\u003e - Indicates whether the user has consented to use their data for advertising purposes.\u003cbr\u003e\n          - \u003ccode\u003ehasConsentForAdsPersonalization\u003c/code\u003e - Indicates whether the user has consented to use their data for personalized advertising purposes.\n        \u003cli\u003e Call \u003ccode\u003eAppsFlyerLib.getInstance().setConsentData()\u003c/code\u003e with the \u003ccode\u003eAppsFlyerConsent\u003c/code\u003e object.    \n        \u003cli\u003e Call \u003ccode\u003eAppsflyerIntegration.startAppsFlyer(this)\u003c/code\u003e. \n      \u003c/ol\u003e\u003cbr\u003e \n    - If GDPR doesn’t apply to the user perform the following: \n      \u003col\u003e \n        \u003cli\u003e Create an \u003ccode\u003eAppsFlyerConsent\u003c/code\u003e object using the \u003ccode\u003eforNonGDPRUser()\u003c/code\u003e method. This method doesn’t accept any parameters.\n        \u003cli\u003e Call \u003ccode\u003eAppsFlyerLib.getInstance().setConsentData()\u003c/code\u003e with the \u003ccode\u003eAppsFlyerConsent\u003c/code\u003e object.  \n        \u003cli\u003e Call \u003ccode\u003eAppsflyerIntegration.startAppsFlyer(this)\u003c/code\u003e. \n      \u003c/ol\u003e \n\u003c/ol\u003e \n\n### \u003ca id=\"sample_app\"\u003e\n\n##  Sample App\n\u003cp\u003eAppsFlyer has created a sample Android application that integrates AppsFlyer via Segment. Check it out at the \u003ca href=\"https://github.com/AppsFlyerSDK/appsflyer-segment-android-plugin/tree/master/segmenttestapp\" target=\"_blank\"\u003eGithub repo\u003c/a\u003e.\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappsflyersdk%2Fappsflyer-segment-android-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fappsflyersdk%2Fappsflyer-segment-android-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappsflyersdk%2Fappsflyer-segment-android-plugin/lists"}