├── app ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── colors.xml │ │ │ └── themes.xml │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── xml │ │ │ └── network_config.xml │ │ ├── layout │ │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── values-night │ │ │ └── themes.xml │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ └── drawable │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ └── dev │ │ │ └── deeplink │ │ │ └── sdk │ │ │ └── demo │ │ │ ├── MainActivity.kt │ │ │ ├── AppLinkActivity.kt │ │ │ └── CustomApplication.kt │ │ └── AndroidManifest.xml ├── .gitignore ├── proguard-rules.pro └── build.gradle.kts ├── gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties └── libs.versions.toml ├── .gitignore ├── settings.gradle.kts ├── gradle.properties └── README.md /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DeepLinkDemo 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DLinkSDK/client-sdk-kotlin/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | gradlew 3 | gradlew.bat 4 | /.idea/ 5 | /.idea/vcs.xml 6 | /.idea/kotlinc.xml 7 | /.idea/misc.xml 8 | /.idea/compiler.xml -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DLinkSDK/client-sdk-kotlin/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DLinkSDK/client-sdk-kotlin/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DLinkSDK/client-sdk-kotlin/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DLinkSDK/client-sdk-kotlin/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DLinkSDK/client-sdk-kotlin/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DLinkSDK/client-sdk-kotlin/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DLinkSDK/client-sdk-kotlin/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DLinkSDK/client-sdk-kotlin/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DLinkSDK/client-sdk-kotlin/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DLinkSDK/client-sdk-kotlin/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/xml/network_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Feb 14 11:50:19 CST 2025 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | gradlew 17 | gradlew.bat 18 | /.idea/ 19 | -------------------------------------------------------------------------------- /app/src/main/java/dev/deeplink/sdk/demo/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.deeplink.sdk.demo 2 | 3 | import android.app.Activity 4 | import android.os.Bundle 5 | 6 | class MainActivity : Activity() { 7 | 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | setContentView(R.layout.activity_main) 11 | } 12 | } -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | agp = "8.4.0" 3 | kotlin = "1.9.0" 4 | appcompat = "1.7.0" 5 | material = "1.12.0" 6 | attribution = "2.5.0" 7 | appsFlyer = "6.12.2" 8 | 9 | [libraries] 10 | androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } 11 | material = { group = "com.google.android.material", name = "material", version.ref = "material" } 12 | attribution = { group = "dev.deeplink.sdk", name = "attribution", version.ref = "attribution" } 13 | appsflyer = { group = "com.appsflyer", name = "af-android-sdk", version.ref = "appsFlyer" } 14 | 15 | [plugins] 16 | android-application = { id = "com.android.application", version.ref = "agp" } 17 | jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } 18 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/java/dev/deeplink/sdk/demo/AppLinkActivity.kt: -------------------------------------------------------------------------------- 1 | package dev.deeplink.sdk.demo 2 | 3 | import android.app.Activity 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import dev.deeplink.sdk.AttrSdk 7 | 8 | /** 9 | * @Author: Hades 10 | * @Date: 2025/11/21 11 | */ 12 | class AppLinkActivity : Activity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | val data = intent.data.toString() 17 | //[Require] Report reEngagement data to Dlink 18 | AttrSdk.trackAppReEngagement(data) 19 | 20 | //[Optional] Execute specific business logic, such as navigating to a specific page. 21 | startActivity(Intent(this, MainActivity::class.java).apply { 22 | this.flags = Intent.FLAG_ACTIVITY_NEW_TASK 23 | }) 24 | 25 | finish() 26 | } 27 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | -keep class dev.deeplink.sdk.bean.**{*;} -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google { 4 | content { 5 | includeGroupByRegex("com\\.android.*") 6 | includeGroupByRegex("com\\.google.*") 7 | includeGroupByRegex("androidx.*") 8 | } 9 | } 10 | mavenCentral() 11 | maven { url = uri("https://maven.deeplink.dev/repository/maven-releases/") } 12 | maven { url = uri("https://jitpack.io") } 13 | gradlePluginPortal() 14 | } 15 | } 16 | dependencyResolutionManagement { 17 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 18 | repositories { 19 | google() 20 | maven { 21 | content { include("dev.deeplink") } 22 | url = uri("https://maven.deeplink.dev/repository/maven-releases/") 23 | } 24 | maven { url = uri("https://jitpack.io") } 25 | mavenCentral() 26 | } 27 | } 28 | 29 | rootProject.name = "DeepLinkDemo" 30 | include(":app") 31 | -------------------------------------------------------------------------------- /app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.android.application) 3 | alias(libs.plugins.jetbrains.kotlin.android) 4 | } 5 | 6 | android { 7 | namespace = "dev.deeplink.sdk.demo" 8 | compileSdk = 34 9 | 10 | defaultConfig { 11 | applicationId = "dev.deeplink.sdk.demo" 12 | minSdk = 23 13 | targetSdk = 34 14 | versionCode = 1 15 | versionName = "1.0.1" 16 | } 17 | 18 | buildTypes { 19 | release { 20 | isMinifyEnabled = true 21 | proguardFiles( 22 | getDefaultProguardFile("proguard-android-optimize.txt"), 23 | "proguard-rules.pro" 24 | ) 25 | } 26 | debug { 27 | isMinifyEnabled = true 28 | proguardFiles( 29 | getDefaultProguardFile("proguard-android-optimize.txt"), 30 | "proguard-rules.pro" 31 | ) 32 | } 33 | } 34 | compileOptions { 35 | sourceCompatibility = JavaVersion.VERSION_1_8 36 | targetCompatibility = JavaVersion.VERSION_1_8 37 | } 38 | kotlinOptions { 39 | jvmTarget = "1.8" 40 | } 41 | } 42 | 43 | dependencies { 44 | 45 | implementation(libs.androidx.appcompat) 46 | implementation(libs.material) 47 | implementation(libs.attribution) 48 | implementation(libs.appsflyer) 49 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. For more details, visit 12 | # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Kotlin code style for this project: "official" or "obsolete": 19 | kotlin.code.style=official 20 | # Enables namespacing of each library's R class so that its R class includes only the 21 | # resources declared in the library itself and none from the library's dependencies, 22 | # thereby reducing the size of the R class for that library 23 | android.nonTransitiveRClass=true -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 34 | 35 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # client-sdk-kotlin 2 | 3 | Step 1: Get the Account ID and DevToken 4 | 5 | Register an account at [https://console.dlink.cloud/](https://console.dlink.cloud). After creating an app on the platform, get the corresponding Account ID and DevToken of the app. 6 | 7 | Step 2: Get the SDK 8 | 9 | (1) Configure the Maven repository 10 | ```kotlin 11 | repositories { 12 | maven { url 'https://maven.deeplink.dev/repository/maven-releases/' } 13 | } 14 | ``` 15 | 16 | Note: The Maven repository address needs to be configured in both 'buildscript' and 'allprojects' in the root directory's 'build.gradle'. 17 | 18 | (2) If you are using Gradle for integration, add the following code to your project's build.gradle: 19 | ```kotlin 20 | implementation 'dev.deeplink.sdk:attribution:2.5.0' 21 | ``` 22 | 23 | Step 3: Configure AndroidManifest 24 | 25 | Find the project configuration file AndroidManifest.xml in your project, and add the following permissions: 26 | 27 | ```kotlin 28 | 29 | 30 | 31 | ``` 32 | 33 | If you enable FB InstallReferrer attribution, you need to add the following configuration: 34 | ```kotlin 35 | 36 | 39 | 42 | 43 | ``` 44 | 45 | If you enable AppsFlyer, you need to add the following configuration: 46 | ```kotlin 47 | implementation("com.appsflyer:af-android-sdk:6.12.2") 48 | ``` 49 | 50 | If you need to add obfuscation during packaging, please add the following code to the obfuscation configuration file: 51 | ```kotlin 52 | -keep class dev.deeplink.sdk.bean.**{*;} 53 | ``` 54 | 55 | Step 4: Initialize the SDK 56 | If your application is in multi-process mode, please initialize the SDK in the main process. Here is the reference code: 57 | ```kotlin 58 | public class MainApplication extends Application { 59 | @Override 60 | public void onCreate() { 61 | super.onCreate(); 62 | if (getBaseContext().getPackageName().equals(getPackageName())) { 63 | // Initialize the SDK 64 | } 65 | } 66 | } 67 | ``` 68 | 69 | This method must be called before all other SDK methods and be successfully initialized. 70 | Other methods will not take effect before successful initialization (except for setting common event attributes). 71 | 72 | ```kotlin 73 | import android.util.Log 74 | import dev.deeplink.sdk.AttrSdk 75 | import dev.deeplink.sdk.OnInitializationCallback 76 | import dev.deeplink.sdk.config.LoggerConfig 77 | import dev.deeplink.sdk.config.ThirdPartyConfig 78 | 79 | val thirdPartyConfig = ThirdPartyConfig().apply { 80 | this.metaAppId = "Meta appId" 81 | this.appsFlyerDevKey = "AppsFlyer Dev Key" 82 | } 83 | AttrSdk.init(context, "ACCOUNT_ID","DEV_TOKEN", thirdPartyConfig, 84 | object : OnInitializationCallback { 85 | override fun onCompleted(code: Int) { 86 | Log.i("Test", "onCompleted -> code($code)") 87 | if (code == 0) { 88 | //Initialization successful 89 | } else { 90 | //Initialization failed, for specific failure reasons refer to the code interpretation 91 | } 92 | } 93 | }) 94 | ``` 95 | 96 | Step 5: Obtain attribution information 97 | 98 | Obtain attribution results via callback 99 | 100 | Developers need to set the attribution information callback interface before the SDK is initialized, otherwise the attribution info callback may not work correctly. 101 | 102 | ```kotlin 103 | import android.util.Log 104 | import dev.deeplink.sdk.AttrSdk 105 | import dev.deeplink.sdk.OnAttributionListener 106 | import org.json.JSONObject 107 | 108 | AttrSdk.setOnAttributionListener(object : OnAttributionListener { 109 | override fun onAttributionSuccess(attribution: JSONObject) { 110 | Log.i("Test","onAttributionSuccess -> $attribution") 111 | } 112 | override fun onAttributionFail(errCode: Int) { 113 | Log.e("Test","onAttributionFail -> $errCode") 114 | } 115 | }) 116 | AttrSdk.init(context, "ACCOUNT_ID","DEV_TOKEN") 117 | ``` 118 | 119 | Directly obtain attribution results 120 | 121 | In addition to adding an attribution result callback when initializing the SDK, you can also directly call and obtain the attribution information after the SDK is initialized. 122 | It should be noted that the method for directly obtaining attribution results will return local cache, so if the local cache has not been generated, the attribution result will be null. 123 | 124 | ```kotlin 125 | import dev.deeplink.sdk.AttrSdk 126 | 127 | AttrSdk.init(context, "ACCOUNT_ID","DEV_TOKEN") 128 | val attribution = AttrSdk.getAttribution() 129 | ``` 130 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/java/dev/deeplink/sdk/demo/CustomApplication.kt: -------------------------------------------------------------------------------- 1 | package dev.deeplink.sdk.demo 2 | 3 | import android.app.Application 4 | import android.util.Log 5 | import dev.deeplink.sdk.AttrSdk 6 | import dev.deeplink.sdk.InAppEventType 7 | import dev.deeplink.sdk.OnAttributionListener 8 | import dev.deeplink.sdk.OnExtraInfoListener 9 | import dev.deeplink.sdk.OnInitializationCallback 10 | import dev.deeplink.sdk.bean.OrderInfo 11 | import dev.deeplink.sdk.bean.ProductInfo 12 | import dev.deeplink.sdk.bean.UserInfo 13 | import dev.deeplink.sdk.config.ThirdPartyConfig 14 | import org.json.JSONObject 15 | 16 | class CustomApplication : Application() { 17 | 18 | companion object { 19 | private const val TAG = "CustomApplication" 20 | } 21 | 22 | override fun onCreate() { 23 | super.onCreate() 24 | 25 | //[Optional] This property is used to identify the source of the installation package to better understand how users obtain the app. 26 | //You can set the property value before initializing the SDK. If not passed in or null is passed in, the default is empty 27 | AttrSdk.setPackageSource("PACKAGE_SOURCE") 28 | 29 | //[Optional] Defaults to false. You can set the property value before initializing the SDK. 30 | //When true is passed, it means that the developer wants to customize the device ID. 31 | //Attribution and events will be reported only when the developer passes in a custom device ID. 32 | //When false is passed, the SDK will generate the device ID internally. 33 | AttrSdk.setWaitForDeviceId(true) 34 | 35 | //[Optional] By default, the SDK will automatically generate a device ID. 36 | //The custom device ID passed by the developer will take effect only when AttrSdk.setWaitForDeviceId is passed true. 37 | AttrSdk.setDeviceId("DEVICE_ID") 38 | 39 | //[Optional] Defaults to false. You can set the property value before initializing the SDK. 40 | // When true is passed, it means that the developer wants to customize the account ID to associate the account with the attribution information. 41 | // Attribution will be reported only if and when the developer passes in a customized account ID. 42 | // When false is passed, the SDK will not generate a account ID internally. 43 | AttrSdk.setWaitForAccountId(true) 44 | 45 | //[Optional] Defaults to empty. Used to associate the account system in the developer's business logic with the attribution information. 46 | AttrSdk.setAccountId("ACCOUNT_ID") 47 | 48 | //[Optional] By default, the SDK will automatically obtain Gaid, and developers do not need to set it manually 49 | //You can set the property value before initializing the SDK. 50 | AttrSdk.setGaid("GAID") 51 | 52 | //[Optional] For pre-installed apps, developers can pass Custom CampaignName and Custom UtmSource for installation attribution 53 | // AttrSdk.setPreInstall(true, "A-B-C-D", "A-B-C-D") 54 | 55 | AttrSdk.setOnAttributionListener(object : OnAttributionListener { 56 | 57 | override fun onAttributionSuccess(attribution: JSONObject) { 58 | //Obtain attribution results successfully 59 | Log.i(TAG, "onAttributionSuccess -> $attribution") 60 | } 61 | 62 | override fun onAttributionFail(errCode: Int) { 63 | //Failed to obtain attribution results 64 | Log.e(TAG, "onAttributionFail -> $errCode") 65 | } 66 | }) 67 | 68 | val thirdPartyConfig = ThirdPartyConfig().apply { 69 | //[Optional] 70 | this.metaAppId = "META_APP_ID" 71 | //[Optional] 72 | this.appsFlyerDevKey = "APPS_FLYER_DEV_KEY" 73 | } 74 | 75 | AttrSdk.setOnExtraInfoListener(object : OnExtraInfoListener { 76 | override fun onUpdate(value: Map) { 77 | Log.i(TAG, "onUpdate -> $value") 78 | } 79 | }) 80 | 81 | AttrSdk.init( 82 | this, "ACCOUNT_ID", "DEV_TOKEN", thirdPartyConfig, 83 | object : OnInitializationCallback { 84 | override fun onCompleted(code: Int) { 85 | Log.i(TAG, "onCompleted -> code($code)") 86 | if (code == 0) { 87 | //Initialization success 88 | logEvents() 89 | } else { 90 | //Initialization failed, for specific failure reasons refer to the code interpretation 91 | } 92 | } 93 | }) 94 | } 95 | 96 | private fun logEvents() { 97 | AttrSdk.setUserInfo(UserInfo().apply { 98 | this.countryName = "COUNTRY_NAME" 99 | this.city = "CITY" 100 | this.emails = mutableListOf("EMAIL1", "EMAIL2") 101 | this.phones = mutableListOf("PHONE1", "PHONE2") 102 | this.firstName = "FIRST_NAME" 103 | this.lastName = "LAST_NAME" 104 | this.fbLoginId = "FB_LOGIN_ID" 105 | }) 106 | 107 | //Users enter the product details page. 108 | AttrSdk.logEvent(InAppEventType.VIEW_CONTENT, hashMapOf().apply { 109 | this[AttrSdk.ORDER_INFO] = OrderInfo( 110 | currency = "", //Ignore 111 | value = 0f, //Ignore 112 | contents = mutableListOf().apply { 113 | this.add( 114 | ProductInfo( 115 | productId = "CONTENT_ID", //Required 116 | productName = "CONTENT_NAME", //Required 117 | quantity = 1, //Required 118 | value = 0f //Ignore 119 | ) 120 | ) 121 | }, 122 | searchString = "", //Ignore 123 | subscribeDay = "" //Ignore 124 | ) 125 | }) 126 | 127 | //The user clicks the "Add to Cart" button. 128 | AttrSdk.logEvent(InAppEventType.ADD_TO_CART, hashMapOf().apply { 129 | this[AttrSdk.ORDER_INFO] = OrderInfo( 130 | currency = "USD", //Required 131 | value = 9.9f, //Required, Total Price 132 | contents = mutableListOf().apply { 133 | this.add( 134 | ProductInfo( 135 | productId = "PRODUCT_ID", //Required 136 | productName = "PRODUCT_NAME", //Required 137 | quantity = 1, //Required 138 | value = 9.9f //Required, Price Each 139 | ) 140 | ) 141 | }, 142 | searchString = "", //Ignore 143 | subscribeDay = "" //Ignore 144 | ) 145 | }) 146 | 147 | //The user has entered the checkout process, but has not yet completed it. 148 | AttrSdk.logEvent(InAppEventType.INITIATE_CHECK_OUT, hashMapOf().apply { 149 | this[AttrSdk.ORDER_INFO] = OrderInfo( 150 | currency = "USD", //Required 151 | value = 9.9f, //Required, Total Price 152 | contents = mutableListOf().apply { 153 | this.add( 154 | ProductInfo( 155 | productId = "PRODUCT_ID", //Required 156 | productName = "PRODUCT_NAME", //Required 157 | quantity = 1, //Required 158 | value = 9.9f //Required, Price Each 159 | ) 160 | ) 161 | }, 162 | searchString = "", //Ignore 163 | subscribeDay = "" //Optional, If it's a subscription product, please enter the number of subscription days. 164 | ) 165 | }) 166 | 167 | // 168 | //Someone has completed the purchase or checkout process. 169 | AttrSdk.logEvent(InAppEventType.PURCHASE, hashMapOf().apply { 170 | //Please enter your real order ID. 171 | this[AttrSdk.EVENT_ID] = "ORDER_ID" //Required 172 | this[AttrSdk.ORDER_INFO] = OrderInfo( 173 | currency = "USD", //Required 174 | value = 9.9f, //Required, Total Price 175 | contents = mutableListOf().apply { 176 | this.add( 177 | ProductInfo( 178 | productId = "PRODUCT_ID", //Required 179 | productName = "PRODUCT_NAME", //Required 180 | quantity = 1, //Required 181 | value = 9.9f //Required, Price Each 182 | ) 183 | ) 184 | }, 185 | searchString = "", //Ignore 186 | subscribeDay = "" //Ignore 187 | ) 188 | }) 189 | 190 | //Someone has applied for a paid subscription service for the goods or services you provide. 191 | AttrSdk.logEvent(InAppEventType.SUBSCRIBE, hashMapOf().apply { 192 | //Please enter your real order ID. 193 | this[AttrSdk.EVENT_ID] = "ORDER_ID" //Required 194 | this[AttrSdk.ORDER_INFO] = OrderInfo( 195 | currency = "USD", //Required 196 | value = 9.9f, //Required, Total Price of contents 197 | contents = mutableListOf().apply { 198 | this.add( 199 | ProductInfo( 200 | productId = "PRODUCT_ID", //Required 201 | productName = "PRODUCT_NAME", //Required 202 | quantity = 1, //Required 203 | value = 9.9f //Required, Price Each 204 | ) 205 | ) 206 | }, 207 | searchString = "", //Ignore 208 | subscribeDay = "30" //Required 209 | ) 210 | }) 211 | } 212 | } --------------------------------------------------------------------------------