From 8189abd5ebbd611140b1c80c6a976426e9c39fea Mon Sep 17 00:00:00 2001 From: andriidudka Date: Tue, 9 Sep 2025 16:54:14 +0300 Subject: [PATCH 1/4] Bump AppsFlyer SDK from 6.13.0 to 6.17.3 Add AppsFlyer Consent documentation --- README.md | 121 ++++++++++++++++++ build.gradle.kts | 2 +- gradle/wrapper/gradle-wrapper.properties | 3 +- lib/build.gradle.kts | 16 ++- lib/src/main/AndroidManifest.xml | 3 +- .../appsflyer/AppsflyerDestination.kt | 28 ++-- 6 files changed, 154 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 37411ab..ddf4dee 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,127 @@ Please use Github issues, Pull Requests, or feel free to reach out to our [suppo Interested in integrating your service with us? Check out our [Partners page](https://segment.com/partners/) for more details. +# AppsFlyer Consent +## Send consent for DMA compliance +For a general introduction to DMA consent data, see [here](https://dev.appsflyer.com/hc/docs/send-consent-for-dma-compliance). +The AppsFlyer 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](https://iabeurope.eu/tcf-supporting-resources/), 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. Create AppsFlyer plugin object val appsFlyerDestination = AppsFlyerDestination(this, true) in the Activity class +
  2. Call appsFlyerDestination.enableTCFDataCollection = true to instruct the AppsFlyer SDK to collect the TCF data from the device. +
  3. Call appsFlyerDestination.startAppsFlyerManually = true.
    This will allow us to delay the Conversion call in order to provide the SDK with the user consent. +
  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 7. +
  6. Get confirmation from the CMP that the user has made their consent decision, and the data is available in SharedPreferences. +
  7. Call AppsFlyerLib.getInstance().start(this) +
+ +#### Activity class +```kotlin +class MainActivity: Activity() { + + private val consentRequired = true + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.activity_main) + + val analytics = Analytics("dev_key", applicationContext) { + this.flushAt = 3 + this.trackApplicationLifecycleEvents = true + } + + val appsFlyerDestination = AppsFlyerDestination(this, true) + if (consentRequired) { + appsFlyerDestination.enableTCFDataCollection = true + appsFlyerDestination.startAppsFlyerManually = true + initConsentCollection() + } + analytics.add(plugin = appsFlyerDestination) + } + + private fun initConsentCollection() { + // Implement here the you CMP flow + // When the flow is completed and consent was collected + // call onConsentCollectionFinished() + } + + private fun onConsentCollectionFinished() { + AppsFlyerLib.getInstance().start(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. Create AppsFlyer plugin object val appsFlyerDestination = AppsFlyerDestination(this, true) in the Activity class +
  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. Call appsFlyerDestination.startAppsFlyerManually = true.
      This will allow us to delay the Conversion call in order to provide the SDK with the user consent. +
    2. Given that GDPR applies 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. +
      +
    3. To transfer the consent data to the SDK, create an object called AppsFlyerConsent with the following optional parameters:
      + - isUserSubjectToGDPR - Indicates whether GDPR applies to the user.
      + - 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.
      + - hasConsentForAdStorage - Indicates whether the user has consented to store or access information on a device.
      +
    4. Call AppsFlyerLib.getInstance().setConsentData() with the AppsFlyerConsent object. +
    5. Call AppsFlyerLib.getInstance().start(this). +

    + - If GDPR does not apply to the user, set isUserSubjectToGDPR to false and the rest of the parameters must be null. See example below: +
      +
    1. Create an AppsFlyerConsent object:
      val nonGdprUser = AppsFlyerConsent(false, null, null, null) +
    2. Call
      AppsFlyerLib.getInstance().setConsentData(nonGdprUser) +
    +
  3. Call analytics.add(plugin = appsFlyerDestination)
    + +```kotlin +class MainActivity: Activity() { + + private val consentRequired = true + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + val analytics = Analytics("dev_key",applicationContext) { + this.flushAt = 3 + this.trackApplicationLifecycleEvents = true + } + + val appsFlyerDestination = AppsFlyerDestination(this, true) + if (consentRequired) { + appsFlyerDestination.startAppsFlyerManually = true + presentConsentCollectionDialog() + } else { + val nonGdprUser = AppsFlyerConsent(false, null, null, null) + AppsFlyerLib.getInstance().setConsentData(nonGdprUser) + } + analytics.add(plugin = appsFlyerDestination) + } + + private fun presentConsentCollectionDialog() { + // When the flow is completed and consent data was collected + // call onConsentCollectionFinished(consent) + } + + private fun onConsentCollectionFinished(consent: AppsFlyerConsent) { + AppsFlyerLib.getInstance().setConsentData(consent) + AppsFlyerLib.getInstance().start(this) + } +} +``` +
+ ## License ``` MIT License diff --git a/build.gradle.kts b/build.gradle.kts index 4b62ca6..c493d55 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -24,7 +24,7 @@ buildscript { dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0") classpath("org.jetbrains.kotlin:kotlin-serialization:1.8.0") - classpath("com.android.tools.build:gradle:7.0.4") + classpath("com.android.tools.build:gradle:8.5.1") } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 69a9715..ec81f67 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Tue Sep 09 15:01:29 EEST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index fbd7932..5a74632 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -10,10 +10,11 @@ val VERSION_NAME: String by project android { compileSdk = 33 + namespace = "com.segment.analytics.kotlin.destinations.appsflyer" defaultConfig { multiDexEnabled = true - minSdk = 16 + minSdk = 19 targetSdk = 33 testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner" @@ -30,15 +31,20 @@ android { } compileOptions { isCoreLibraryDesugaringEnabled = true - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "17" + } + + buildFeatures { + buildConfig = true } } dependencies { + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") implementation("com.segment.analytics.kotlin:android:1.14.2") implementation("androidx.multidex:multidex:2.0.1") @@ -51,7 +57,7 @@ dependencies { // Partner Dependencies dependencies { - implementation("com.appsflyer:af-android-sdk:6.13.0") + implementation ("com.appsflyer:af-android-sdk:6.17.3") implementation ("com.android.installreferrer:installreferrer:2.2") } diff --git a/lib/src/main/AndroidManifest.xml b/lib/src/main/AndroidManifest.xml index 883baa9..a5918e6 100644 --- a/lib/src/main/AndroidManifest.xml +++ b/lib/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + \ No newline at end of file diff --git a/lib/src/main/java/com/segment/analytics/kotlin/destinations/appsflyer/AppsflyerDestination.kt b/lib/src/main/java/com/segment/analytics/kotlin/destinations/appsflyer/AppsflyerDestination.kt index a26c13a..c1a0fb8 100644 --- a/lib/src/main/java/com/segment/analytics/kotlin/destinations/appsflyer/AppsflyerDestination.kt +++ b/lib/src/main/java/com/segment/analytics/kotlin/destinations/appsflyer/AppsflyerDestination.kt @@ -60,7 +60,7 @@ data class AppsFlyerSettings( ) class AppsFlyerDestination( - private val applicationContext: Context, + private val activityContext: Context, private var isDebug: Boolean = false ) : DestinationPlugin(), AndroidLifecycle, VersionedPlugin { @@ -72,6 +72,9 @@ class AppsFlyerDestination( var conversionListener: ExternalAppsFlyerConversionListener? = null var deepLinkListener: ExternalDeepLinkListener? = null + var startAppsFlyerManually: Boolean = false + var enableTCFDataCollection: Boolean? = null + override val key: String = "AppsFlyer" override fun setup(analytics: Analytics) { @@ -91,8 +94,17 @@ class AppsFlyerDestination( if (it.trackAttributionData) { listener = ConversionListener() } - appsflyer?.setDebugLog(isDebug) - appsflyer?.init(it.appsFlyerDevKey, listener, applicationContext) + appsflyer?.apply { + setDebugLog(isDebug) + init(it.appsFlyerDevKey, listener, activityContext) + enableTCFDataCollection?.let { enabled -> + enableTCFDataCollection(enabled) + } + if (!startAppsFlyerManually) { + start(activityContext) + analytics.log("AppsFlyerLib.getInstance().start($activityContext)") + } + } } } deepLinkListener?.let { @@ -119,17 +131,13 @@ class AppsFlyerDestination( val afProperties = properties.mapTransform(propertiesMapper).mapValues { (_, v) -> v.toContent() } - appsflyer?.logEvent(applicationContext, event, afProperties) + appsflyer?.logEvent(activityContext, event, afProperties) analytics.log("appsflyer.logEvent(context, $event, $properties)") return payload } override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) { super.onActivityCreated(activity, savedInstanceState) - if (activity != null) { - AppsFlyerLib.getInstance().start(activity) - analytics.log("AppsFlyerLib.getInstance().start($activity)") - } updateEndUserAttributes() } @@ -227,13 +235,13 @@ class AppsFlyerDestination( private fun getFlag(key: String): Boolean { val sharedPreferences: SharedPreferences = - applicationContext.getSharedPreferences(AF_SEGMENT_SHARED_PREF, 0) + activityContext.getSharedPreferences(AF_SEGMENT_SHARED_PREF, 0) return sharedPreferences.getBoolean(key, false) } private fun setFlag(key: String, value: Boolean) { val sharedPreferences: SharedPreferences = - applicationContext.getSharedPreferences(AF_SEGMENT_SHARED_PREF, 0) + activityContext.getSharedPreferences(AF_SEGMENT_SHARED_PREF, 0) val editor = sharedPreferences.edit() editor.putBoolean(key, value).apply() } From d0e3bd33ec6df6bb2cb2447a3169278dab13234a Mon Sep 17 00:00:00 2001 From: andriidudka Date: Tue, 9 Sep 2025 17:01:15 +0300 Subject: [PATCH 2/4] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ddf4dee..4b7bf69 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,9 @@ If your app does not use a CMP compatible with TCF v2.2, use the SDK API detaile
  • Call
    AppsFlyerLib.getInstance().setConsentData(nonGdprUser)
  • Call analytics.add(plugin = appsFlyerDestination)
    - + + +#### Activity class ```kotlin class MainActivity: Activity() { From d20fb9983841ee5da6aeaae094908073a1c7686f Mon Sep 17 00:00:00 2001 From: andriidudka Date: Wed, 10 Sep 2025 14:46:54 +0300 Subject: [PATCH 3/4] Update README.md --- README.md | 123 +---------------------------------------- docs/API_GUIDELINES.md | 122 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 122 deletions(-) create mode 100644 docs/API_GUIDELINES.md diff --git a/README.md b/README.md index 4b7bf69..8c64bb8 100644 --- a/README.md +++ b/README.md @@ -51,128 +51,7 @@ Please use Github issues, Pull Requests, or feel free to reach out to our [suppo Interested in integrating your service with us? Check out our [Partners page](https://segment.com/partners/) for more details. -# AppsFlyer Consent -##
    Send consent for DMA compliance -For a general introduction to DMA consent data, see [here](https://dev.appsflyer.com/hc/docs/send-consent-for-dma-compliance). -The AppsFlyer 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](https://iabeurope.eu/tcf-supporting-resources/), 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. Create AppsFlyer plugin object val appsFlyerDestination = AppsFlyerDestination(this, true) in the Activity class -
    2. Call appsFlyerDestination.enableTCFDataCollection = true to instruct the AppsFlyer SDK to collect the TCF data from the device. -
    3. Call appsFlyerDestination.startAppsFlyerManually = true.
      This will allow us to delay the Conversion call in order to provide the SDK with the user consent. -
    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 7. -
    6. Get confirmation from the CMP that the user has made their consent decision, and the data is available in SharedPreferences. -
    7. Call AppsFlyerLib.getInstance().start(this) -
    - -#### Activity class -```kotlin -class MainActivity: Activity() { - - private val consentRequired = true - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - setContentView(R.layout.activity_main) - - val analytics = Analytics("dev_key", applicationContext) { - this.flushAt = 3 - this.trackApplicationLifecycleEvents = true - } - - val appsFlyerDestination = AppsFlyerDestination(this, true) - if (consentRequired) { - appsFlyerDestination.enableTCFDataCollection = true - appsFlyerDestination.startAppsFlyerManually = true - initConsentCollection() - } - analytics.add(plugin = appsFlyerDestination) - } - - private fun initConsentCollection() { - // Implement here the you CMP flow - // When the flow is completed and consent was collected - // call onConsentCollectionFinished() - } - - private fun onConsentCollectionFinished() { - AppsFlyerLib.getInstance().start(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. Create AppsFlyer plugin object val appsFlyerDestination = AppsFlyerDestination(this, true) in the Activity class -
    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. Call appsFlyerDestination.startAppsFlyerManually = true.
        This will allow us to delay the Conversion call in order to provide the SDK with the user consent. -
      2. Given that GDPR applies 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. -
        -
      3. To transfer the consent data to the SDK, create an object called AppsFlyerConsent with the following optional parameters:
        - - isUserSubjectToGDPR - Indicates whether GDPR applies to the user.
        - - 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.
        - - hasConsentForAdStorage - Indicates whether the user has consented to store or access information on a device.
        -
      4. Call AppsFlyerLib.getInstance().setConsentData() with the AppsFlyerConsent object. -
      5. Call AppsFlyerLib.getInstance().start(this). -

      - - If GDPR does not apply to the user, set isUserSubjectToGDPR to false and the rest of the parameters must be null. See example below: -
        -
      1. Create an AppsFlyerConsent object:
        val nonGdprUser = AppsFlyerConsent(false, null, null, null) -
      2. Call
        AppsFlyerLib.getInstance().setConsentData(nonGdprUser) -
      -
    3. Call analytics.add(plugin = appsFlyerDestination)
      - - -#### Activity class -```kotlin -class MainActivity: Activity() { - - private val consentRequired = true - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - val analytics = Analytics("dev_key",applicationContext) { - this.flushAt = 3 - this.trackApplicationLifecycleEvents = true - } - - val appsFlyerDestination = AppsFlyerDestination(this, true) - if (consentRequired) { - appsFlyerDestination.startAppsFlyerManually = true - presentConsentCollectionDialog() - } else { - val nonGdprUser = AppsFlyerConsent(false, null, null, null) - AppsFlyerLib.getInstance().setConsentData(nonGdprUser) - } - analytics.add(plugin = appsFlyerDestination) - } - - private fun presentConsentCollectionDialog() { - // When the flow is completed and consent data was collected - // call onConsentCollectionFinished(consent) - } - - private fun onConsentCollectionFinished(consent: AppsFlyerConsent) { - AppsFlyerLib.getInstance().setConsentData(consent) - AppsFlyerLib.getInstance().start(this) - } -} -``` -
    +## For guidelines on API integrations, please refer to [this](docs/API_GUIDELINES.md) page ## License ``` diff --git a/docs/API_GUIDELINES.md b/docs/API_GUIDELINES.md new file mode 100644 index 0000000..1544e84 --- /dev/null +++ b/docs/API_GUIDELINES.md @@ -0,0 +1,122 @@ +##
    Send consent for DMA compliance +For a general introduction to DMA consent data, see [here](https://dev.appsflyer.com/hc/docs/send-consent-for-dma-compliance). +The AppsFlyer 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](https://iabeurope.eu/tcf-supporting-resources/), 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. Create AppsFlyer plugin object val appsFlyerDestination = AppsFlyerDestination(this, true) in the Activity class +
    2. Call appsFlyerDestination.enableTCFDataCollection = true to instruct the AppsFlyer SDK to collect the TCF data from the device. +
    3. Call appsFlyerDestination.startAppsFlyerManually = true.
      This will allow us to delay the Conversion call in order to provide the SDK with the user consent. +
    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 7. +
    6. Get confirmation from the CMP that the user has made their consent decision, and the data is available in SharedPreferences. +
    7. Call AppsFlyerLib.getInstance().start(this) +
    + +#### Activity class +```kotlin +class MainActivity: Activity() { + + private val consentRequired = true + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.activity_main) + + val analytics = Analytics("dev_key", applicationContext) { + this.flushAt = 3 + this.trackApplicationLifecycleEvents = true + } + + val appsFlyerDestination = AppsFlyerDestination(this, true) + if (consentRequired) { + appsFlyerDestination.enableTCFDataCollection = true + appsFlyerDestination.startAppsFlyerManually = true + initConsentCollection() + } + analytics.add(plugin = appsFlyerDestination) + } + + private fun initConsentCollection() { + // Implement here the you CMP flow + // When the flow is completed and consent was collected + // call onConsentCollectionFinished() + } + + private fun onConsentCollectionFinished() { + AppsFlyerLib.getInstance().start(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. Create AppsFlyer plugin object val appsFlyerDestination = AppsFlyerDestination(this, true) in the Activity class +
    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. Call appsFlyerDestination.startAppsFlyerManually = true.
        This will allow us to delay the Conversion call in order to provide the SDK with the user consent. +
      2. Given that GDPR applies 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. +
        +
      3. To transfer the consent data to the SDK, create an object called AppsFlyerConsent with the following optional parameters:
        + - isUserSubjectToGDPR - Indicates whether GDPR applies to the user.
        + - 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.
        + - hasConsentForAdStorage - Indicates whether the user has consented to store or access information on a device.
        +
      4. Call AppsFlyerLib.getInstance().setConsentData() with the AppsFlyerConsent object. +
      5. Call AppsFlyerLib.getInstance().start(this). +

      + - If GDPR does not apply to the user, set isUserSubjectToGDPR to false and the rest of the parameters must be null. See example below: +
        +
      1. Create an AppsFlyerConsent object:
        val nonGdprUser = AppsFlyerConsent(false, null, null, null) +
      2. Call
        AppsFlyerLib.getInstance().setConsentData(nonGdprUser) +
      +
    3. Call analytics.add(plugin = appsFlyerDestination)
      + + +#### Activity class +```kotlin +class MainActivity: Activity() { + + private val consentRequired = true + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + val analytics = Analytics("dev_key",applicationContext) { + this.flushAt = 3 + this.trackApplicationLifecycleEvents = true + } + + val appsFlyerDestination = AppsFlyerDestination(this, true) + if (consentRequired) { + appsFlyerDestination.startAppsFlyerManually = true + presentConsentCollectionDialog() + } else { + val nonGdprUser = AppsFlyerConsent(false, null, null, null) + AppsFlyerLib.getInstance().setConsentData(nonGdprUser) + } + analytics.add(plugin = appsFlyerDestination) + } + + private fun presentConsentCollectionDialog() { + // When the flow is completed and consent data was collected + // call onConsentCollectionFinished(consent) + } + + private fun onConsentCollectionFinished(consent: AppsFlyerConsent) { + AppsFlyerLib.getInstance().setConsentData(consent) + AppsFlyerLib.getInstance().start(this) + } +} +``` +
    + From dac93dd1e66df6f5a2182af5a8364246821de685 Mon Sep 17 00:00:00 2001 From: andriidudka Date: Wed, 10 Sep 2025 14:48:49 +0300 Subject: [PATCH 4/4] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c64bb8..8d42218 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Please use Github issues, Pull Requests, or feel free to reach out to our [suppo Interested in integrating your service with us? Check out our [Partners page](https://segment.com/partners/) for more details. -## For guidelines on API integrations, please refer to [this](docs/API_GUIDELINES.md) page +### For guidelines on API integrations, please refer to [this](docs/API_GUIDELINES.md) page ## License ```