{"id":19167371,"url":"https://github.com/affise/sdk-android","last_synced_at":"2025-05-07T13:41:27.451Z","repository":{"id":49443058,"uuid":"496592599","full_name":"affise/sdk-android","owner":"affise","description":"Affise Attribution Android SDK","archived":false,"fork":false,"pushed_at":"2025-05-02T12:09:14.000Z","size":3133,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-02T13:24:30.809Z","etag":null,"topics":["affise","android","metrics","mobile","sdk"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","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/affise.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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,"zenodo":null}},"created_at":"2022-05-26T11:26:19.000Z","updated_at":"2025-05-02T12:09:17.000Z","dependencies_parsed_at":"2024-03-12T14:34:10.546Z","dependency_job_id":"bf3b78ee-c4e1-4b6a-aac2-0dfd9e87a86a","html_url":"https://github.com/affise/sdk-android","commit_stats":null,"previous_names":[],"tags_count":81,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affise%2Fsdk-android","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affise%2Fsdk-android/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affise%2Fsdk-android/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/affise%2Fsdk-android/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/affise","download_url":"https://codeload.github.com/affise/sdk-android/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252889094,"owners_count":21820114,"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":["affise","android","metrics","mobile","sdk"],"created_at":"2024-11-09T09:37:01.929Z","updated_at":"2025-05-07T13:41:27.440Z","avatar_url":"https://github.com/affise.png","language":"Kotlin","readme":"# Affise Attribution Android Library\n\n[Change Log](CHANGELOG.md)\n\n| Artifact                         | Version                                                                                                                                                                         |\n|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `com.affise:attribution`         | [![attribution](https://img.shields.io/maven-central/v/com.affise/attribution?label=latest)](https://mvnrepository.com/artifact/com.affise/attribution)                         |\n| `com.affise:module-advertising`  | [![module-advertising](https://img.shields.io/maven-central/v/com.affise/module-advertising?label=latest)](https://mvnrepository.com/artifact/com.affise/module-advertising)    |\n| `com.affise:module-androidid`    | [![module-androidid](https://img.shields.io/maven-central/v/com.affise/module-androidid?label=latest)](https://mvnrepository.com/artifact/com.affise/module-androidid)          |\n| `com.affise:module-link`         | [![module-link](https://img.shields.io/maven-central/v/com.affise/module-link?label=latest)](https://mvnrepository.com/artifact/com.affise/module-link)                         |\n| `com.affise:module-network`      | [![module-network](https://img.shields.io/maven-central/v/com.affise/module-network?label=latest)](https://mvnrepository.com/artifact/com.affise/module-network)                |\n| `com.affise:module-phone`        | [![module-phone](https://img.shields.io/maven-central/v/com.affise/module-phone?label=latest)](https://mvnrepository.com/artifact/com.affise/module-phone)                      |\n| `com.affise:module-status`       | [![module-status](https://img.shields.io/maven-central/v/com.affise/module-status?label=latest)](https://mvnrepository.com/artifact/com.affise/module-status)                   |\n| `com.affise:module-subscription` | [![module-subscription](https://img.shields.io/maven-central/v/com.affise/module-subscription?label=latest)](https://mvnrepository.com/artifact/com.affise/module-subscription) |\n| `com.affise:module-rustore`      | [![module-rustore](https://img.shields.io/maven-central/v/com.affise/module-rustore?label=latest)](https://mvnrepository.com/artifact/com.affise/module-rustore)                |\n| `com.affise:module-huawei`       | [![module-huawei](https://img.shields.io/maven-central/v/com.affise/module-huawei?label=latest)](https://mvnrepository.com/artifact/com.affise/module-huawei)                   |\n| `com.affise:module-meta`         | [![module-meta](https://img.shields.io/maven-central/v/com.affise/module-meta?label=latest)](https://mvnrepository.com/artifact/com.affise/module-meta)                   |\n\n- [Affise Attribution Android Library](#affise-attribution-android-library)\n- [Description](#description)\n  - [Quick start](#quick-start)\n  - [Integration](#integration)\n    - [Integrate as dependency](#integrate-as-dependency)\n    - [Integrate as file dependency](#integrate-as-file-dependency)\n    - [Initialize](#initialize)\n      - [Before application is published](#before-application-is-published)\n      - [Domain](#domain)\n    - [Modules](#modules)\n      - [Module Advertising](#module-advertising)\n      - [Module Huawei](#module-huawei)\n      - [Module Link](#module-link)\n      - [Module Meta](#module-meta)\n      - [Module Status](#module-status)\n      - [Module Subscription](#module-subscription)\n        - [AffiseProductType](#affiseproducttype)\n    - [Requirements](#requirements)\n- [Features](#features)\n  - [ProviderType identifiers collection](#providertype-identifiers-collection)\n    - [Attribution](#attribution)\n    - [Advertising](#advertising)\n    - [AndroidId](#androidid)\n    - [Huawei](#huawei)\n    - [Meta](#meta)\n    - [Network](#network)\n    - [Phone](#phone)\n  - [Event send control](#event-send-control)\n  - [Events tracking](#events-tracking)\n  - [Custom events tracking](#custom-events-tracking)\n  - [Predefined event parameters](#predefined-event-parameters)\n    - [PredefinedString](#predefinedstring)\n    - [PredefinedLong](#predefinedlong)\n    - [PredefinedFloat](#predefinedfloat)\n    - [PredefinedObject](#predefinedobject)\n    - [PredefinedListObject](#predefinedlistobject)\n    - [PredefinedListString](#predefinedliststring)\n  - [Events buffering](#events-buffering)\n  - [Advertising Identifier (google) tracking](#advertising-identifier-google-tracking)\n  - [Open Advertising Identifier (huawei) tracking](#open-advertising-identifier-huawei-tracking)\n  - [Install referrer tracking](#install-referrer-tracking)\n  - [Push token tracking](#push-token-tracking)\n  - [Reinstall Uninstall tracking](#reinstall-uninstall-tracking)\n  - [APK preinstall tracking](#apk-preinstall-tracking)\n  - [Links](#links)\n    - [Deeplinks](#deeplinks)\n    - [AppLinks](#applinks)\n    - [Get deferred deeplink](#get-deferred-deeplink)\n    - [Get deferred deeplink value](#get-deferred-deeplink-value)\n  - [Offline mode](#offline-mode)\n  - [Disable tracking](#disable-tracking)\n  - [Disable background tracking](#disable-background-tracking)\n  - [GDPR right to be forgotten](#gdpr-right-to-be-forgotten)\n  - [Get referrer](#get-referrer)\n  - [Get referrer parameter](#get-referrer-parameter)\n  - [Referrer keys](#referrer-keys)\n  - [Get module state](#get-module-state)\n  - [Get random user Id](#get-random-user-id)\n  - [Get random device Id](#get-random-device-id)\n  - [Get providers](#get-providers)\n  - [Is first run](#is-first-run)\n  - [WebView tracking](#webview-tracking)\n    - [Initialize WebView](#initialize-webview)\n    - [Events tracking JS](#events-tracking-js)\n    - [Predefined event parameters JS](#predefined-event-parameters-js)\n    - [Custom events JS](#custom-events-js)\n  - [Custom](#custom)\n    - [ConversionId](#conversionid)\n- [SDK to SDK integrations](#sdk-to-sdk-integrations)\n  - [AdMob](#admob)\n  - [AppLovin MAX](#applovin-max)\n  - [Helium by Chartboost](#helium-by-chartboost)\n  - [ironSource](#ironsource)\n  - [Admost](#admost)\n- [Debug](#debug)\n  - [Validate credentials](#validate-credentials)\n  - [Version](#version)\n    \n# Description\n\nAffise SDK is a software you can use to collect app usage statistics, device identifiers, deeplink usage, track install\nreferrer.\n\n## Quick start\n\n## Integration\n\n### Integrate as dependency\n\nFor kotlin build script build.gradle.kts use:\n\n```kotlin\nval affise_version = \"1.6.57\"\n\ndependencies {\n  // Add Affise library \n  implementation(\"com.affise:attribution:$affise_version\")\n  // Add Affise modules \n  implementation(\"com.affise:module-advertising:$affise_version\")\n  implementation(\"com.affise:module-androidid:$affise_version\")\n  implementation(\"com.affise:module-link:$affise_version\")\n  implementation(\"com.affise:module-network:$affise_version\")\n  implementation(\"com.affise:module-phone:$affise_version\")\n  implementation(\"com.affise:module-status:$affise_version\")\n  implementation(\"com.affise:module-subscription:$affise_version\")\n  // implementation(\"com.affise:module-rustore:$affise_version\")\n  // implementation(\"com.affise:module-huawei:$affise_version\")\n  // Add install referrer\n  implementation(\"com.android.installreferrer:installreferrer:2.2\")\n}\n```\n\nFor groovy build script build.gradle use:\n\n```groovy\nfinal affise_version = '1.6.57'\n\ndependencies {\n    // Add Affise library \n    implementation \"com.affise:attribution:$affise_version\"\n    // Add Affise modules \n    implementation \"com.affise:module-advertising:$affise_version\"\n    implementation \"com.affise:module-androidid:$affise_version\"\n    implementation \"com.affise:module-link:$affise_version\"\n    implementation \"com.affise:module-network:$affise_version\"\n    implementation \"com.affise:module-phone:$affise_version\"\n    implementation \"com.affise:module-status:$affise_version\"\n    implementation \"com.affise:module-subscription:$affise_version\"\n    // implementation \"com.affise:module-rustore:$affise_version\"\n    // implementation \"com.affise:module-huawei:$affise_version\"\n    // Add install referrer\n    implementation 'com.android.installreferrer:installreferrer:2.2'\n}\n```\n\n### Integrate as file dependency\n\nDownload latest Affise SDK (`attribution-1.6.57.aar`)\nfrom [releases page](https://github.com/affise/sdk-android/releases) and place this binary to gradle application\nmodule lib directory `app/libs/attribution-1.6.57.aar`\n\nAdd library as gradle file dependency to application module build script\nAdd install referrer library\n\nFor kotlin build script build.gradle.kts use:\n\n```kotlin\nval affise_version = \"1.6.57\"\n\ndependencies {\n    // ...\n    // Add Affise library \n    implementation(files(\"libs/attribution-1.6.57.aar\"))\n    // Add Affise modules \n    implementation(files(\"libs/module-advertising-$affise_version.aar\"))\n    implementation(files(\"libs/module-androidid-$affise_version.aar\"))\n    implementation(files(\"libs/module-link-$affise_version.aar\"))\n    implementation(files(\"libs/module-network-$affise_version.aar\"))\n    implementation(files(\"libs/module-phone-$affise_version.aar\"))\n    implementation(files(\"libs/module-status-$affise_version.aar\"))\n    implementation(files(\"libs/module-subscription-$affise_version.aar\"))\n    // implementation(files(\"libs/module-rustore-$affise_version.aar\"))\n    // implementation(files(\"libs/module-huawei-$affise_version.aar\"))\n    // Add install referrer\n    implementation(\"com.android.installreferrer:installreferrer:2.2\")\n}\n```\n\nFor groovy build script build.gradle use:\n\n```groovy\nfinal affise_version = '1.6.57'\n\ndependencies {\n  // ...  \n  // Add Affise library \n  implementation files(\"libs/attribution-${affise_version}.aar\")\n  // Add Affise modules \n  implementation files(\"libs/module-advertising-${affise_version}.aar\")\n  implementation files(\"libs/module-androidid-${affise_version}.aar\")\n  implementation files(\"libs/module-link-${affise_version}.aar\")\n  implementation files(\"libs/module-network-${affise_version}.aar\")\n  implementation files(\"libs/module-phone-${affise_version}.aar\")\n  implementation files(\"libs/module-status-${affise_version}.aar\")\n  implementation files(\"libs/module-subscription-${affise_version}.aar\")\n  // implementation files(\"libs/module-rustore-${affise_version}.aar\")\n  // implementation files(\"libs/module-huawei-${affise_version}.aar\")\n  // Add install referrer\n  implementation 'com.android.installreferrer:installreferrer:2.2'\n}\n```\n\n### Initialize\n\nAfter library is added as dependency sync project with gradle files and initialize.\n\n\u003e Demo app [App.kt](app/src/main/java/com/affise/app/App.kt)\n\nFor kotlin use:\n\n```kotlin\nclass App : Application() {\n    override fun onCreate() {\n        super.onCreate()\n        \n        Affise\n            .settings(\n                affiseAppId = \"Your appId\", //Change to your app id\n                secretKey = \"Your SDK secretKey\", //Change to your SDK secretKey\n            )\n            .start(this) // Start Affise SDK\n    }\n}\n```\n\nFor java use:\n\n```java\npublic class App extends Application {\n    @Override\n    public void onCreate() {\n        super.onCreate();\n      \n        Affise\n            .settings(\n                \"Your appId\", //Change to your app id\n                \"Your SDK secretKey\" //Change to your SDK secretKey\n            )\n            .start(this); // Start Affise SDK\n    }\n}\n```\n\nCheck if library is initialized\n\n```kotlin\nAffise\n    .settings(\n        affiseAppId = \"Your appId\",\n        secretKey = \"Your SDK secretKey\",\n    )\n    .setOnInitSuccess {\n        // Called then library is initialized\n    }\n    .start(this)\n```\n\n#### Before application is published\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e\n\u003e Please make sure your credentials are valid\n\u003e\n\u003e Visit section [validation credentials](#validate-credentials)\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\n#### Domain\n\nSet SDK server domain:\n\n```kotlin\nclass App : Application() {\n    override fun onCreate() {\n        super.onCreate()\n        \n        Affise\n            .settings(\n                affiseAppId = \"Your appId\",\n                secretKey = \"Your SDK secretKey\",\n            )\n            .setDomain(\"https://YoureCustomDomain/\") // Set custom domain\n            .start(this) // Start Affise SDK\n    }\n}\n```\n\n### Modules\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e \n\u003e How to install modules read in [Integration section](#integration)\n\u003e \n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\n| Module         | Version                                                                                                                                                                         | Start  |\n|:---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------:|\n| `Advertising`  | [![module-advertising](https://img.shields.io/maven-central/v/com.affise/module-advertising?label=latest)](https://mvnrepository.com/artifact/com.affise/module-advertising)    | `Auto` |\n| `AndroidId`    | [![module-androidid](https://img.shields.io/maven-central/v/com.affise/module-androidid?label=latest)](https://mvnrepository.com/artifact/com.affise/module-androidid)          | `Auto` |\n| `Link`         | [![module-link](https://img.shields.io/maven-central/v/com.affise/module-link?label=latest)](https://mvnrepository.com/artifact/com.affise/module-link)                         | `Auto` |\n| `Network`      | [![module-network](https://img.shields.io/maven-central/v/com.affise/module-network?label=latest)](https://mvnrepository.com/artifact/com.affise/module-network)                | `Auto` |\n| `Phone`        | [![module-phone](https://img.shields.io/maven-central/v/com.affise/module-phone?label=latest)](https://mvnrepository.com/artifact/com.affise/module-phone)                      | `Auto` |\n| `Status`       | [![module-status](https://img.shields.io/maven-central/v/com.affise/module-status?label=latest)](https://mvnrepository.com/artifact/com.affise/module-status)                   | `Auto` |\n| `Subscription` | [![module-subscription](https://img.shields.io/maven-central/v/com.affise/module-subscription?label=latest)](https://mvnrepository.com/artifact/com.affise/module-subscription) | `Auto` |\n| `RuStore`      | [![module-rustore](https://img.shields.io/maven-central/v/com.affise/module-rustore?label=latest)](https://mvnrepository.com/artifact/com.affise/module-rustore)                | `Auto` |\n| `Huawei`       | [![module-huawei](https://img.shields.io/maven-central/v/com.affise/module-huawei?label=latest)](https://mvnrepository.com/artifact/com.affise/module-huawei)                   | `Auto` |\n| `Meta`         | [![module-meta](https://img.shields.io/maven-central/v/com.affise/module-meta?label=latest)](https://mvnrepository.com/artifact/com.affise/module-meta)                     | `Auto` |\n\nIf module start type is `Manual`, then call:\n\n```kotlin\nAffise.Module.moduleStart(AffiseModules.Advertising)\n```\n\nGet list of installed modules:\n\n```kotlin\nAffise.Module.getModulesInstalled()\n```\n\n#### Module Advertising\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e\n\u003e For module `Advertising` to send GAID (Google Advertising ID)\n\u003e \n\u003e Uses `com.google.android.gms:play-services-ads-identifier`\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\n```kotlin\nval gaid = Affise.getProviders()[ProviderType.GAID_ADID] as? String\n```\n\n#### Module Huawei\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e\n\u003e Use [Huawei Module](#modules) to get OAID (Open Advertising Identifier)\n\u003e\n\u003e Uses `com.huawei.hms:ads-identifier`\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\n```kotlin\nval oaid = Affise.getProviders()[ProviderType.OAID] as? String\n```\n\n#### Module Link\n\nReturn last url in chan of redirection\n\n🟥Support MAX 10 redirections🟥\n\n```kotlin\nAffise.Module.linkResolve(\"SITE_WITH_REDIRECTION\") { redirectUrl -\u003e\n    // handle redirect url\n}\n```\n\nFor java use:\n\n```java\nAffiseLink.linkResolve(\"SITE_WITH_REDIRECTION\", redirectUrl -\u003e {\n    // handle redirect url  \n});\n```\n\n#### Module Meta\n\n- [Meta Install Referrer Docs](https://developers.facebook.com/docs/app-ads/meta-install-referrer)\n- [Google's Install Referral Docs](https://developer.android.com/google/play/installreferrer)\n\n1. Add `queries` to your `AndroidManifest.xml`\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cmanifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\u003e\n    \u003cqueries\u003e\n        \u003cpackage android:name=\"com.facebook.katana\" /\u003e\n        \u003cpackage android:name=\"com.instagram.android\" /\u003e\n        \u003cpackage android:name=\"com.facebook.lite\" /\u003e\n    \u003c/queries\u003e\n\n    \u003capplication\u003e\n      ...\n    \u003c/application\u003e\n\u003c/manifest\u003e\n```\n\n2. Add your `Facebook App Id` as config value `AffiseConfig.FbAppId` in `Affise.settings`\n\n```kotlin\nAffise\n    .settings(\n        affiseAppId = \"Your appId\",\n        secretKey = \"Your SDK secretKey\",\n    )\n    .setConfigValue(AffiseConfig.FbAppId, \"Your Facebook App Id\")\n    .start(this)\n```\n\n#### Module Status\n\n```kotlin\nAffise.Module.getStatus(AffiseModules.Status) { response -\u003e\n  // handle response\n}\n```\n\n#### Module Subscription\n\nGet products by ids:\n\n```kotlin\nval ids = [\"exampple.product.id_1\", \"exampple.product.id_2\"]\n\nAffise.Module.fetchProducts(ids) { result -\u003e\n    when (result) {\n        is AffiseResult.Success -\u003e {\n          val products: List\u003cAffiseProduct\u003e = result.value.products\n          val invalidIds: List\u003cString\u003e = result.value.invalidIds\n        }\n        is AffiseResult.Error -\u003e {\n          val error: String = result.error.message\n        }\n    }\n}\n```\n\nPurchase product:\n\n```kotlin\n// Specify AffiseProductType for correct affise event\nAffise.Module.purchase(activity, product, AffiseProductType.CONSUMABLE) { result -\u003e\n    when (result) {\n        is AffiseResult.Success -\u003e {\n          val purchasedInfo: AffisePurchasedInfo  = result.value\n        }\n        is AffiseResult.Error -\u003e {\n          val error: String = result.error.message\n        }\n    }\n}\n```\n\n##### AffiseProductType\n\n- `CONSUMABLE`\n- `NON_CONSUMABLE`\n- `RENEWABLE_SUBSCRIPTION`\n- `NON_RENEWABLE_SUBSCRIPTION`\n\n### Requirements\n\nFor a minimal working functionality your app needs to declare internet permission:\n\n```xml\n\n\u003cmanifest\u003e\n  \u003c!-- ... --\u003e\n  \u003cuses-permission android:name=\"android.permission.INTERNET\"/\u003e\n\u003c/manifest\u003e\n```\n\n# Features\n\n## ProviderType identifiers collection\n\nTo match users with events and data library is sending, these `ProviderType` identifiers are collected:\n\n### Attribution\n\n- `AFFISE_APP_ID`\n- `AFFISE_PKG_APP_NAME`\n- `AFF_APP_NAME_DASHBOARD`\n- `APP_VERSION`\n- `APP_VERSION_RAW`\n- `STORE`\n- `TRACKER_TOKEN`\n- `TRACKER_NAME`\n- `FIRST_TRACKER_TOKEN`\n- `FIRST_TRACKER_NAME`\n- `LAST_TRACKER_TOKEN`\n- `LAST_TRACKER_NAME`\n- `OUTDATED_TRACKER_TOKEN`\n- `INSTALLED_TIME`\n- `FIRST_OPEN_TIME`\n- `INSTALLED_HOUR`\n- `FIRST_OPEN_HOUR`\n- `INSTALL_FIRST_EVENT`\n- `INSTALL_BEGIN_TIME`\n- `INSTALL_FINISH_TIME`\n- `REFERRER_INSTALL_VERSION`\n- `REFERRAL_TIME`\n- `REFERRER_CLICK_TIME`\n- `REFERRER_CLICK_TIME_SERVER`\n- `REFERRER_GOOGLE_PLAY_INSTANT`\n- `CREATED_TIME`\n- `CREATED_TIME_MILLI`\n- `CREATED_TIME_HOUR`\n- `UNINSTALL_TIME`\n- `REINSTALL_TIME`\n- `LAST_SESSION_TIME`\n- `CPU_TYPE`\n- `HARDWARE_NAME`\n- `DEVICE_MANUFACTURER`\n- `DEEPLINK_CLICK`\n- `DEVICE_ATLAS_ID`\n- `AFFISE_DEVICE_ID`\n- `AFFISE_ALT_DEVICE_ID`\n- `REFTOKEN`\n- `REFTOKENS`\n- `REFERRER`\n- `USER_AGENT`\n- `MCCODE`\n- `MNCODE`\n- `REGION`\n- `COUNTRY`\n- `LANGUAGE`\n- `DEVICE_NAME`\n- `DEVICE_TYPE`\n- `OS_NAME`\n- `PLATFORM`\n- `SDK_PLATFORM`\n- `API_LEVEL_OS`\n- `AFFISE_SDK_VERSION`\n- `OS_VERSION`\n- `RANDOM_USER_ID`\n- `AFFISE_SDK_POS`\n- `TIMEZONE_DEV`\n- `AFFISE_EVENT_NAME`\n- `AFFISE_EVENT_TOKEN`\n- `LAST_TIME_SESSION`\n- `TIME_SESSION`\n- `AFFISE_SESSION_COUNT`\n- `LIFETIME_SESSION_COUNT`\n- `AFFISE_DEEPLINK`\n- `AFFISE_PART_PARAM_NAME`\n- `AFFISE_PART_PARAM_NAME_TOKEN`\n- `AFFISE_APP_TOKEN`\n- `LABEL`\n- `AFFISE_SDK_SECRET_ID`\n- `UUID`\n- `AFFISE_APP_OPENED`\n- `PUSHTOKEN`\n- `AFFISE_EVENTS_COUNT`\n- `AFFISE_SDK_EVENTS_COUNT`\n- `AFFISE_METRICS_EVENTS_COUNT`\n- `AFFISE_INTERNAL_EVENTS_COUNT`\n- `IS_ROOTED`\n- `IS_EMULATOR`\n\n### Advertising\n\n- `GAID_ADID`\n- `GAID_ADID_MD5`\n- `ADID`\n- `ALTSTR_ADID`\n- `FIREOS_ADID`\n- `COLOROS_ADID`\n- `AD_PERSONALIZATION`\n\n### AndroidId\n\n- `ANDROID_ID`\n- `ANDROID_ID_MD5`\n\n### Huawei\n\n- `OAID`\n- `OAID_MD5`\n\n### Meta\n\n- `META`\n\n### Network\n\n- `MAC_SHA1`\n- `MAC_MD5`\n- `CONNECTION_TYPE`\n- `PROXY_IP_ADDRESS`\n\n### Phone\n\n- `NETWORK_TYPE`\n- `ISP`\n\n## Event send control\n\nThere are two ways to send events\n\n1. Cache event to later scheduled send in batch\n\n```kotlin\nAddToCartEvent()\n    .send()\n```\n\n2. Send event right now\n\n```kotlin\nAddToCartEvent()\n    .sendNow({\n        // handle event send success\n    }) { errorResponse -\u003e\n      // handle event send failed\n      // 🟥Warning:🟥 event is NOT cached for later send\n    }\n```\n\n## Events tracking\n\n\u003e Demo app [DefaultEventsFactory.kt](app/src/main/java/com/affise/app/ui/screen/buttons/factories/DefaultEventsFactory.kt)\n\nFor example, we want to track what items usually user adds to shopping cart. To send event first create it with\nfollowing code\n\n```kotlin\nclass Presenter {\n  fun onUserAddsItemsToCart(userData: String) {\n    AddToCartEvent(userData)\n        .send() // Send event\n  }\n}\n```\n\nFor java use:\n\n```java\nclass Presenter {\n  void onUserAddsItemsToCart(String userData) {\n    new AddToCartEvent(userData)\n            .send(); // Send event\n  }\n}\n```\n\nWith above example you can implement other events:\n\n- `AchieveLevel`\n- `AddPaymentInfo`\n- `AddToCart`\n- `AddToWishlist`\n- `AdRevenue`\n- `ClickAdv`\n- `CompleteRegistration`\n- `CompleteStream`\n- `CompleteTrial`\n- `CompleteTutorial`\n- `Contact`\n- `ContentItemsView`\n- `CustomizeProduct`\n- `DeepLinked`\n- `Donate`\n- `FindLocation`\n- `InitiateCheckout`\n- `InitiatePurchase`\n- `InitiateStream`\n- `Invite`\n- `LastAttributedTouch`\n- `Lead`\n- `ListView`\n- `Login`\n- `OpenedFromPushNotification`\n- `Order`\n- `OrderItemAdded`\n- `OrderItemRemove`\n- `OrderCancel`\n- `OrderReturnRequest`\n- `OrderReturnRequestCancel`\n- `Purchase`\n- `Rate`\n- `ReEngage`\n- `Reserve`\n- `Sales`\n- `Schedule`\n- `Search`\n- `Share`\n- `SpendCredits`\n- `StartRegistration`\n- `StartTrial`\n- `StartTutorial`\n- `SubmitApplication`\n- `Subscribe`\n- `TravelBooking`\n- `UnlockAchievement`\n- `Unsubscribe`\n- `Update`\n- `ViewAdv`\n- `ViewCart`\n- `ViewContent`\n- `ViewItem`\n- `ViewItems`\n- `InitialSubscription`\n- `InitialTrial`\n- `InitialOffer`\n- `ConvertedTrial`\n- `ConvertedOffer`\n- `TrialInRetry`\n- `OfferInRetry`\n- `SubscriptionInRetry`\n- `RenewedSubscription`\n- `FailedSubscriptionFromRetry`\n- `FailedOfferFromRetry`\n- `FailedTrialFromRetry`\n- `FailedSubscription`\n- `FailedOfferise`\n- `FailedTrial`\n- `ReactivatedSubscription`\n- `RenewedSubscriptionFromRetry`\n- `ConvertedOfferFromRetry`\n- `ConvertedTrialFromRetry`\n- `Unsubscription`\n\n## Custom events tracking\n\nUse any of custom events if default doesn't fit your scenario:\n\n- `CustomId01`\n- `CustomId02`\n- `CustomId03`\n- `CustomId04`\n- `CustomId05`\n- `CustomId06`\n- `CustomId07`\n- `CustomId08`\n- `CustomId09`\n- `CustomId10`\n\nIf above event functionality still limits your usecase, you can use `UserCustomEvent`\n\n```kotlin\nUserCustomEvent(\"MyCustomEvent\")\n    .send() \n```\n\n## Predefined event parameters\n\nTo enrich your event with another dimension, you can use predefined parameters for most common cases.\nAdd it to any event:\n\n```kotlin\nclass Presenter {\n  fun onUserAddsItemsToCart(userData: String) {\n    AddToCartEvent(userData)\n        .addPredefinedParameter(PredefinedString.DESCRIPTION, \"best before 2029\")\n        .addPredefinedParameter(PredefinedObject.CONTENT, JSONObject().apply {\n          put(\"collection\", \"Greatest Hits\")\n        })\n        .addPredefinedParameter(PredefinedListObject.CONTENT_LIST, listOf(\n          JSONObject().apply {\n            put(\"content\", \"songs, videos\")\n          }\n        ))\n        .send() // Send event\n  }\n}\n```\n\nFor java use:\n\n```java\nclass Presenter {\n  void onUserAddsItemsToCart(String userData) {\n    JSONObject json = new JSONObject()\n            .put(\"collection\", \"Greatest Hits\");\n    \n    JSONObject jsonContent = new JSONObject()\n            .put(\"content\", \"songs, videos\");\n    \n    List\u003cJSONObject\u003e jsonList = Collections.singletonList(jsonContent);\n    \n    new AddToCartEvent(userData, System.currentTimeMillis())\n            .addPredefinedParameter(PredefinedString.DESCRIPTION, \"best before 2029\")\n            .addPredefinedParameter(PredefinedFloat.PRICE, 2.19f)\n            .addPredefinedParameter(PredefinedObject.CONTENT, json)\n            .addPredefinedParameter(PredefinedListObject.CONTENT_LIST, jsonList)\n            .send(); // Send event\n  }\n}\n```\n\nIn examples above `PredefinedString.DESCRIPTION` and `PredefinedFloat.PRICE` is used, but many others is available:\n\n| PredefinedParameter                           | Type                   |\n|-----------------------------------------------|------------------------|\n| [PredefinedString](#predefinedstring)         | String                 |\n| [PredefinedLong](#predefinedlong)             | Long                   |\n| [PredefinedFloat](#predefinedfloat)           | Float                  |\n| [PredefinedObject](#predefinedobject)         | JSONObject             |\n| [PredefinedListObject](#predefinedlistobject) | List\u0026lt;JSONObject\u0026gt; |\n| [PredefinedListString](#predefinedliststring) | List\u0026lt;String\u0026gt;     |\n\n### PredefinedString\n\n- `ACHIEVEMENT_ID`\n- `ADREV_AD_TYPE`\n- `BRAND`\n- `BRICK`\n- `CAMPAIGN_ID`\n- `CATALOGUE_ID`\n- `CHANNEL_TYPE`\n- `CITY`\n- `CLASS`\n- `CLICK_ID`\n- `CONTENT_ID`\n- `CONTENT_NAME`\n- `CONTENT_TYPE`\n- `CONVERSION_ID`\n- `COUNTRY`\n- `COUPON_CODE`\n- `CURRENCY`\n- `CUSTOMER_SEGMENT`\n- `CUSTOMER_TYPE`\n- `CUSTOMER_USER_ID`\n- `DEEP_LINK`\n- `DESCRIPTION`\n- `DESTINATION_A`\n- `DESTINATION_B`\n- `DESTINATION_LIST`\n- `EVENT_NAME`\n- `NEW_VERSION`\n- `NETWORK`\n- `OLD_VERSION`\n- `ORDER_ID`\n- `PARAM_01`\n- `PARAM_02`\n- `PARAM_03`\n- `PARAM_04`\n- `PARAM_05`\n- `PARAM_06`\n- `PARAM_07`\n- `PARAM_08`\n- `PARAM_09`\n- `PARAM_10`\n- `PAYMENT_INFO_AVAILABLE`\n- `PID`\n- `PLACEMENT`\n- `PREFERRED_NEIGHBORHOODS`\n- `PRODUCT_ID`\n- `PRODUCT_NAME`\n- `PURCHASE_CURRENCY`\n- `RECEIPT_ID`\n- `REGION`\n- `REGISTRATION_METHOD`\n- `REVIEW_TEXT`\n- `SEARCH_STRING`\n- `SEGMENT`\n- `SOURCE`\n- `STATUS`\n- `SUBSCRIPTION_ID`\n- `SUCCESS`\n- `SUGGESTED_DESTINATIONS`\n- `SUGGESTED_HOTELS`\n- `TUTORIAL_ID`\n- `UNIT`\n- `UTM_CAMPAIGN`\n- `UTM_MEDIUM`\n- `UTM_SOURCE`\n- `VALIDATED`\n- `VERTICAL`\n- `VIRTUAL_CURRENCY_NAME`\n- `VOUCHER_CODE`\n\n### PredefinedLong\n\n- `AMOUNT`\n- `DATE_A`\n- `DATE_B`\n- `DEPARTING_ARRIVAL_DATE`\n- `DEPARTING_DEPARTURE_DATE`\n- `HOTEL_SCORE`\n- `LEVEL`\n- `MAX_RATING_VALUE`\n- `NUM_ADULTS`\n- `NUM_CHILDREN`\n- `NUM_INFANTS`\n- `PREFERRED_NUM_STOPS`\n- `PREFERRED_STAR_RATINGS`\n- `QUANTITY`\n- `RATING_VALUE`\n- `RETURNING_ARRIVAL_DATE`\n- `RETURNING_DEPARTURE_DATE`\n- `SCORE`\n- `TRAVEL_START`\n- `TRAVEL_END`\n- `USER_SCORE`\n- `EVENT_START`\n- `EVENT_END`\n\n### PredefinedFloat\n\n- `PREFERRED_PRICE_RANGE`\n- `PRICE`\n- `REVENUE`\n- `LAT`\n- `LONG`\n\n### PredefinedObject\n\n- `CONTENT`\n\n### PredefinedListObject\n\n- `CONTENT_LIST`\n\n### PredefinedListString\n\n- `CONTENT_IDS`\n\n## Events buffering\n\nAffise library will send any pending events with first opportunity,\nbut if there is no network connection or device is disabled, events are kept locally for 7 days before deletion.\n\n## Advertising Identifier (google) tracking\n\n\u003e **Note**\n\u003e\n\u003e Requires [Affise Advertising Module](#modules)\n\nAdvertising Identifier (google) tracking is supported automatically, no actions needed\n\n## Open Advertising Identifier (huawei) tracking\n\n\u003e **Note**\n\u003e\n\u003e Requires [Affise Huawei Module](#modules)\n\nOpen Advertising Identifier is supported automatically, no actions needed\n\n## Install referrer tracking\n\nInstall referrer tracking is supported automatically, no actions needed\n\n## Push token tracking\n\nTo let affise track push token you need to receive it from your push service provider, and pass to Affise library.\nFirst add firebase integration to your app completing these steps: [Firebase Docs](https://firebase.google.com/docs/cloud-messaging/android/client)\n\nAfter you have done with firebase integration, add to your cloud messaging service `onNewToken` method `Affise.addPushToken(token)`\n\n```kotlin\nclass FirebaseCloudMessagingService : FirebaseMessagingService() {\n  override fun onNewToken(token: String) {\n    // New token generated\n    Affise.addPushToken(token)\n  }\n}\n```\n\n## Reinstall Uninstall tracking\n\nAffise automatically track reinstall events by using silent-push technology, to make this feature work, pass push token when it is recreated by user and on you application starts up\n\n```kotlin\nAffise.addPushToken(token)\n```\n\n## APK preinstall tracking\n\nSDK is also supports scenario when APK is installed not from one of application markets, such as google play, huawei appgallery or amazon appstore\nTo use this feature, create file with name `partner_key` in your app assets directory, and write unique identifier inside, this key will be passed to our backend so you can track events by partner later in your Affise console.\n\n## Links\n\n### Deeplinks\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e\n\u003e Deeplinks support only **CUSTOM** scheme **NOT** `http` or `https`\n\u003e\n\u003e For `http` or `https` read how to setup [AppLinks](#applinks)\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\nTo integrate deeplink support you need:\n\n- Add intent filter to one of your activities\n- Add **custom** scheme (**NOT** `http` or `https`) and host to filter\n\nExample: `YOUR_SCHEME://YOUR_DOMAIN`\n\nExample: `myapp://mydomain.com`\n\n```xml\n\u003cintent-filter android:autoVerify=\"true\"\u003e\n  \u003caction android:name=\"android.intent.action.VIEW\" /\u003e\n  \u003ccategory android:name=\"android.intent.category.DEFAULT\" /\u003e\n  \u003ccategory android:name=\"android.intent.category.BROWSABLE\" /\u003e\n  \u003cdata android:scheme=\"YOUR_SCHEME\" /\u003e\n  \u003cdata android:host=\"YOUR_DOMAIN\" /\u003e\n\u003c/intent-filter\u003e\n```\n\n- Register deeplink callback right after `Affise.settings(..).start(..)`\n\nfor kotlin:\n\n```kotlin\nAffise.settings(affiseAppId, secretKey).start(context) // Start Affise SDK\n\nAffise.registerDeeplinkCallback { value -\u003e\n    // full uri \"scheme://host/path?parameters\"   \n    val deeplink = value.deeplink\n    \n    // separated for convenience \n    val scheme = value.scheme\n    val host = value.host\n    val path = value.path\n    val queryParametersMap = value.parameters\n    \n    if(queryParametersMap[\"\u003cyour_uri_key\u003e\"].contains(\"\u003cyour_uri_key_value\u003e\")) {\n        // handle value\n    }\n}\n```\n\nfor java:\n\n```java\nAffise.registerDeeplinkCallback(value -\u003e {\n    // full uri \"scheme://host/path?parameters\"   \n    String deeplink = value.getDeeplink();\n\n    // separated for convenience \n    String scheme = value.getScheme();\n    String host = value.getHost();\n    String path = value.getPath();\n    Map\u003cString, List\u003cString\u003e\u003e queryParametersMap = value.getParameters();\n    \n    if (queryParametersMap.get(\"your_uri_key\").contains(\"your_uri_key_value\")) {\n        // handle value\n    }\n});\n```\n\nTest DeepLink via terminal command:\n\n```terminal\nadb shell am start -a android.intent.action.VIEW -d \"YOUR_SCHEME://YOUR_DOMAIN/somepath?param=1\\\u0026list=some\\\u0026list=other\\\u0026list=\"\n```\n\n### AppLinks\n\n\u003e **Warning**\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e\n\u003e You must own website domain.\n\u003e\n\u003e And has ability to add file `https://yoursite/.well-known/assetlinks.json`\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\nTo integrate applink support you need:\n\n- Add intent filter to one of your activities\n- Add `https` or `http` scheme and host to filter\n\nExample: `https://YOUR_DOMAIN`\n\nExample: `https://mydomain.com`\n\n```xml\n\u003cintent-filter android:autoVerify=\"true\"\u003e\n  \u003caction android:name=\"android.intent.action.VIEW\" /\u003e\n  \u003ccategory android:name=\"android.intent.category.DEFAULT\" /\u003e\n  \u003ccategory android:name=\"android.intent.category.BROWSABLE\" /\u003e\n  \u003cdata android:scheme=\"https\" /\u003e\n  \u003cdata android:host=\"YOUR_DOMAIN\" /\u003e\n\u003c/intent-filter\u003e\n```\n\n- Associate your app with your website. [Read Google instructions](https://developer.android.com/studio/write/app-link-indexing#associatesite) \u003cdetails\u003e\n  \u003csummary\u003eHow To Associate your app with your website\u003c/summary\u003e\n  \n  ---\n\n  After setting up URL support for your app, the App Links Assistant generates a Digital Assets Links file you can use to [associate your website with your app](https://developer.android.com/training/app-links/verify-android-applinks#web-assoc).\n\n  As an alternative to using the Digital Asset Links file, you can [associate your site and app in Search Console](https://support.google.com/webmasters/answer/6212023).\n\n  If you're using [Play App Signing](https://support.google.com/googleplay/android-developer/answer/9842756) for your app, then the certificate fingerprint produced by the App Links Assistant usually doesn't match the one on users' devices. In this case, you can find the correct Digital Asset Links JSON snippet for your app in your [Play Console](https://play.google.com/console/) developer account under **Release** \u003e **Setup** \u003e **App signing**.\n\n  To associate your app and your website using the App Links Assistant, click **Open Digital Asset Links File Generator** from the App Links Assistant and follow these steps:\n\n  ![app-links-assistant-dal-file-generator_2x](https://developer.android.com/static/studio/images/write/app-links-assistant-dal-file-generator_2x.png)\n  **Figure 2**. Enter details about your site and app to generate a Digital Asset Links file.\n\n  1. Enter your **Site domain** and your [**Application ID**](https://developer.android.com/studio/build/configure-app-module#set-application-id).\n  \n  2. To include support in your Digital Asset Links file for [One Tap sign-in](https://developers.google.com/identity/one-tap/android/overview), select **Support sharing credentials between the app and the website** and enter your site's sign-in URL.This adds the following string to your Digital Asset Links file declaring that your app and website share sign-in credentials: `delegate_permission/common.get_login_creds`.\n\n  3. Specify the [signing config](https://developer.android.com/studio/publish/app-signing#sign-auto) or select a [keystore file](https://developer.android.com/studio/publish/app-signing#certificates-keystores).\n\n  Make sure you select the right release config or keystore file for the release build or the debug config or keystore file for the debug build of your app. If you want to set up your production build, use the release config. If you want to test your build, use the debug config.\n\n  4. Click **Generate Digital Asset Links file**.\n  5. Once Android Studio generates the file, click **Save file** to download it.\n  6. Upload the `assetlinks.json` file to your site, with read access for everyone, at `https://yoursite/.well-known/assetlinks.json`.\n\n  \u003e **Important**\n  \u003e\n  \u003e The system verifies the Digital Asset Links file via the encrypted HTTPS protocol. Make sure that the **assetlinks.json** file is accessible over an HTTPS connection, regardless of whether your app's intent filter includes **https**.\n\n  7. Click **Link and Verify** to confirm that you've uploaded the correct Digital Asset Links file to the correct location.\n\n  Learn more about associating your website with your app through the Digital Asset Links file in Declare website associations.\n  \n  ---\n\n\u003c/details\u003e\n\n- Register deeplink callback right after `Affise.settings(..).start(..)`\n\nfor kotlin:\n\n```kotlin\nAffise.settings(affiseAppId, secretKey).start(context) // Start Affise SDK\n\nAffise.registerDeeplinkCallback { value -\u003e\n    // full uri \"scheme://host/path?parameters\"   \n    val deeplink = value.deeplink\n  \n    // separated for convenience \n    val scheme = value.scheme\n    val host = value.host\n    val path = value.path\n    val queryParametersMap = value.parameters\n  \n    if(queryParametersMap[\"\u003cyour_uri_key\u003e\"].contains(\"\u003cyour_uri_key_value\u003e\")) {\n        // handle value\n    }\n}\n```\n\nfor java:\n\n```java\nAffise.registerDeeplinkCallback(value -\u003e {\n    // full uri \"scheme://host/path?parameters\"   \n    String deeplink = value.getDeeplink();\n    \n    // separated for convenience \n    String scheme = value.getScheme();\n    String host = value.getHost();\n    String path = value.getPath();\n    Map\u003cString, List\u003cString\u003e\u003e queryParametersMap = value.getParameters();\n      \n    if (queryParametersMap.get(\"your_uri_key\").contains(\"your_uri_key_value\")) {\n        // handle value\n    }\n});\n```\n\nTest AppLinks via terminal command:\n\n```terminal\nadb shell am start -a android.intent.action.VIEW -d \"https://YOUR_DOMAIN/somepath?param=1\\\u0026list=some\\\u0026list=other\\\u0026list=\"\n```\n\n\n### Get deferred deeplink\n\n\u003e **Note**\n\u003e\n\u003e Requires [Affise Status Module](#modules)\n\nUse the next public method of SDK\n\n```kotlin\nAffise.getDeferredDeeplink { deferredDeeplink -\u003e\n  // handle deferred deeplink\n}\n```\n\n### Get deferred deeplink value\n\n\u003e **Note**\n\u003e\n\u003e Requires [Affise Status Module](#modules)\n\nUse the next public method of SDK to get referrer parameter by\n\n```kotlin\nAffise.getDeferredDeeplinkValue(ReferrerKey.CLICK_ID) { deferredDeeplinkValue -\u003e\n  // handle deferred deeplink value\n}\n```\n\n## Offline mode\n\nIn some scenarios you would want to limit Affise network usage, to pause that activity call anywhere in your application following code after Affise init:\n\n```kotlin\nAffise.settings(affiseAppId, secretKey).start(context) // Start Affise SDK\n\nAffise.setOfflineModeEnabled(true) // to enable offline mode\nAffise.setOfflineModeEnabled(false) // to disable offline mode\n```\n\nWhile offline mode is enabled, your metrics and other events are kept locally, and will be delivered once offline mode is disabled.\nOffline mode is persistent as Application lifecycle, and will be disabled with process termination automatically.\nTo check current offline mode status call:\n\n```kotlin\nAffise.isOfflineModeEnabled() // returns true or false describing current tracking state\n```\n\n## Disable tracking\n\nTo disable any tracking activity, storing events and gathering device identifiers and metrics call anywhere in your application following code after Affise init:\n\n```kotlin\nAffise.settings(affiseAppId, secretKey).start(context) // Start Affise SDK\n\nAffise.setTrackingEnabled(true) // to enable tracking\nAffise.setTrackingEnabled(false) // to disable tracking\n```\n\nBy default tracking is enabled.\n\nWhile tracking mode is disabled, metrics and other identifiers is not generated locally.\nKeep in mind that this flag is persistent until app reinstall, and don't forget to reactivate tracking when needed.\nTo check current status of tracking call:\n\n```kotlin\nAffise.isTrackingEnabled() // returns true or false describing current tracking state\n```\n\n## Disable background tracking\n\nTo disable any background tracking activity, storing events and gathering device identifiers and metrics call anywhere in your application following code after Affise init:\n\n```kotlin\nAffise.settings(affiseAppId, secretKey).start(context) // Start Affise SDK\n\nAffise.setBackgroundTrackingEnabled(true) // to enable background tracking\nAffise.setBackgroundTrackingEnabled(false) // to disable background tracking\n```\n\nBy default background tracking is enabled.\n\nWhile background tracking mode is disabled, metrics and other identifiers is not generated locally.\nBackground tracking mode is persistent as Application lifecycle, and will be re-enabled with process termination automatically.\nTo check current status of background tracking call:\n\n```kotlin\nAffise.isBackgroundTrackingEnabled() // returns true or false describing current background tracking state\n```\n\n## GDPR right to be forgotten\n\nUnder the EU's General Data Protection Regulation (GDPR): An individual has the right to have their personal data erased.\nTo provide this functionality to user, as the app developer, you can call\n\n```kotlin\nAffise.settings(affiseAppId, secretKey).start(context) // Start Affise SDK\n\nAffise.forget() // to forget users data\n```\n\nAfter processing such request our backend servers will delete all users data.\nTo prevent library from generating new events, disable tracking just before calling Affise.forget:\n\n```kotlin\nAffise.settings(affiseAppId, secretKey).start(context) // Start Affise SDK\n\nAffise.setTrackingEnabled(false)\nAffise.forget() // to forget users data\n```\n\n## Get referrer\n\nUse the next public method of SDK\n\n\u003e To get Install referrer by installing from RuStore include module [`RuStore`](#modules)\n\n\u003e To get Install referrer by installing from AppGallery include module [`Huawei`](#modules)\n\nFor kotlin:\n\n```kotlin\nAffise.getReferrerUrl { referrer -\u003e\n  // handle referrer\n}\n```\n\nFor java:\n\n```java\nAffise.getReferrerUrl(referrer -\u003e {\n    // handle referrer\n});\n```\n\n## Get referrer parameter\n\nUse the next public method of SDK to get referrer parameter by\n\n\u003e To get Install referrer by installing from RuStore include module [`RuStore`](#modules)\n\n\u003e To get Install referrer by installing from AppGallery include module [`Huawei`](#modules)\n\nFor kotlin:\n\n```kotlin\nAffise.getReferrerUrlValue(ReferrerKey.CLICK_ID) { value -\u003e\n  // handle referrer value\n}\n```\n\nFor java:\n\n```java\nAffise.getReferrerUrlValue(ReferrerKey.CLICK_ID, value -\u003e {\n    // handle referrer value\n});\n```\n\n## Referrer keys\n\nIn examples above `ReferrerKey.CLICK_ID` is used, but many others is available:\n\n- `AD_ID`\n- `CAMPAIGN_ID`\n- `CLICK_ID`\n- `AFFISE_AD`\n- `AFFISE_AD_ID`\n- `AFFISE_AD_TYPE`\n- `AFFISE_ADSET`\n- `AFFISE_ADSET_ID`\n- `AFFISE_AFFC_ID`\n- `AFFISE_CHANNEL`\n- `AFFISE_CLICK_LOOK_BACK`\n- `AFFISE_COST_CURRENCY`\n- `AFFISE_COST_MODEL`\n- `AFFISE_COST_VALUE`\n- `AFFISE_DEEPLINK`\n- `AFFISE_KEYWORDS`\n- `AFFISE_MEDIA_TYPE`\n- `AFFISE_MODEL`\n- `AFFISE_OS`\n- `AFFISE_PARTNER`\n- `AFFISE_REF`\n- `AFFISE_SITE_ID`\n- `AFFISE_SUB_SITE_ID`\n- `AFFISE_SUB_1`\n- `AFFISE_SUB_2`\n- `AFFISE_SUB_3`\n- `AFFISE_SUB_4`\n- `AFFISE_SUB_5`\n- `AFFC`\n- `PID`\n- `SUB_1`\n- `SUB_2`\n- `SUB_3`\n- `SUB_4`\n- `SUB_5`\n\n## Get module state\n\nGet state of the module:\n\nFor kotlin:\n\n```kotlin\nAffise.Module.getStatus(AffiseModules.Status) { response -\u003e\n  // handle response\n}\n```\n\nFor java:\n\n```java\nAffise.Module.getStatus(AffiseModules.Status, response -\u003e {\n    // handle response\n});\n```\n\n## Get random user Id\n\nUse the next public method of SDK\n\nFor kotlin:\n\n```kotlin\nAffise.getRandomUserId()\n```\n\n## Get random device Id\n\n\u003e **Note**\n\u003e\n\u003e Use [Affise AndroidId Module](#modules) to make `device id` more persistent on application reinstall\n\nUse the next public method of SDK\n\nFor kotlin:\n\n```kotlin\nAffise.getRandomDeviceId()\n```\n\n## Get providers\n\nReturns providers map with [ProviderType](#providertype-identifiers-collection) as key\n\n```kotlin\nval providers: Map\u003cProviderType, Any?\u003e = Affise.getProviders()\nval key = ProviderType.AFFISE_APP_TOKEN\nval value = providers[key]\n```\n\n## Is first run\n\nUse the next public method of SDK\n\nFor kotlin:\n\n```kotlin\nAffise.isFirstRun()\n```\n\n## WebView tracking\n\n### Initialize WebView\n\nTo integrate the library into the JavaScript environment, we added a bridge between JavaScript and the native SDK. Now you can send events and use the functionality of the native library directly from WebView.\nHere are step by step instructions:\n\n```kotlin\n// retrieve WebView from view hierarchy\nval webView = findViewById\u003cWebView\u003e(R.Id.your_webview_id)\n// make sure javascript is enabled\nwebView.javaScriptEnabled = true\n// initialize WebView with Affise native library\nAffise.registerWebView(webView)\n```\n\nOther Javascript environment features is described below.\n\n### Events tracking JS\n\n\u003e Demo app [index.html](app/src/main/assets/index.html)\n\nAfter WebView is initialized you send events from JavaScript environment\n\n```javascript\nlet data = { card: 4138, type: 'phone' };\nnew AddPaymentInfoEvent({\n  userData: 'taxi',\n})\n  .addPredefinedParameter(PredefinedString.PURCHASE_CURRENCY, 'USD')\n  .addPredefinedParameter(PredefinedObject.CONTENT, data)\n  .addPredefinedParameter(PredefinedFloat.PRICE, 2.19)\n  .send(); // Send event\n```\n\nJust like with native SDK, javascript environment also provides default events that can be passed from WebView:\n\n- `AchieveLevelEvent`\n- `AddPaymentInfoEvent`\n- `AddToCartEvent`\n- `AddToWishlistEvent`\n- `AdRevenueEvent`\n- `ClickAdvEvent`\n- `CompleteRegistrationEvent`\n- `CompleteStreamEvent`\n- `CompleteTrialEvent`\n- `CompleteTutorialEvent`\n- `ContactEvent`\n- `ContentItemsViewEvent`\n- `CustomId01Event`\n- `CustomId02Event`\n- `CustomId03Event`\n- `CustomId04Event`\n- `CustomId05Event`\n- `CustomId06Event`\n- `CustomId07Event`\n- `CustomId08Event`\n- `CustomId09Event`\n- `CustomId10Event`\n- `CustomizeProductEvent`\n- `DeepLinkedEvent`\n- `DonateEvent`\n- `FindLocationEvent`\n- `InitiateCheckoutEvent`\n- `InitiatePurchaseEvent`\n- `InitiateStreamEvent`\n- `InviteEvent`\n- `LastAttributedTouchEvent`\n- `LeadEvent`\n- `ListViewEvent`\n- `LoginEvent`\n- `OpenedFromPushNotificationEvent`\n- `OrderEvent`\n- `OrderItemAddedEvent`\n- `OrderItemRemoveEvent`\n- `OrderCancelEvent`\n- `OrderReturnRequestEvent`\n- `OrderReturnRequestCancelEvent`\n- `PurchaseEvent`\n- `RateEvent`\n- `ReEngageEvent`\n- `ReserveEvent`\n- `SalesEvent`\n- `ScheduleEvent`\n- `SearchEvent`\n- `ShareEvent`\n- `SpendCreditsEvent`\n- `StartRegistrationEvent`\n- `StartTrialEvent`\n- `StartTutorialEvent`\n- `SubmitApplicationEvent`\n- `SubscribeEvent`\n- `TravelBookingEvent`\n- `UnlockAchievementEvent`\n- `UnsubscribeEvent`\n- `UpdateEvent`\n- `ViewAdvEvent`\n- `ViewCartEvent`\n- `ViewContentEvent`\n- `ViewItemEvent`\n- `ViewItemsEvent`\n- `InitialSubscriptionEvent`\n- `InitialTrialEvent`\n- `InitialOfferEvent`\n- `ConvertedTrialEvent`\n- `ConvertedOfferEvent`\n- `TrialInRetryEvent`\n- `OfferInRetryEvent`\n- `SubscriptionInRetryEvent`\n- `RenewedSubscriptionEvent`\n- `FailedSubscriptionFromRetryEvent`\n- `FailedOfferFromRetryEvent`\n- `FailedTrialFromRetryEvent`\n- `FailedSubscriptionEvent`\n- `FailedOfferiseEvent`\n- `FailedTrialEvent`\n- `ReactivatedSubscriptionEvent`\n- `RenewedSubscriptionFromRetryEvent`\n- `ConvertedOfferFromRetryEvent`\n- `ConvertedTrialFromRetryEvent`\n- `UnsubscriptionEvent`\n\n### Predefined event parameters JS\n\nEach event can be extended with custom event parameters. By calling `addPredefinedParameter` function you can pass [predefined parameters](#predefinedstring)\n\nFor example:\n\n```javascript\nlet event = ...\n\nevent\n  .addPredefinedParameter(PredefinedString.PURCHASE_CURRENCY, 'USD')\n  .addPredefinedParameter(PredefinedFloat.PRICE, 2.19)\n  .addPredefinedParameter(PredefinedLong.QUANTITY, 1)\n  .addPredefinedParameter(PredefinedObject.CONTENT, { card: 4138, type: 'phone' })\n  .addPredefinedParameter(PredefinedListObject.CONTENT_LIST, [{content:'songs'}, {content:'videos'}])\n  .send(); // Send event\n```\n\n### Custom events JS\n\nIf above event functionality still limits your use case, you can always extend `Event` class to override fields you are missing\n\n```javascript\nclass MyCustomEvent extends Event {\n    constructor(args) {\n        super('MyCustom', args)\n    }\n}\n```\n\n## Custom\n\n### ConversionId\n\nAdds 3 PredefinedString values: `PredefinedString.CONVERSION_ID`, `PredefinedString.ORDER_ID`, `PredefinedString.PRODUCT_ID`\n\n\u003e `CONVERSION_ID` = `ORDER_ID`_`PRODUCT_ID`\n\n```kotlin\nval event = AddToCartEvent()\n\nval conversionId = event.customPredefined().conversionId(\"ORDER_ID\", \"PRODUCT_ID\")\n\nevent.send() // Send event\n```\n\n# SDK to SDK integrations\n\n## AdMob\n\nFor more information how to setup, please check [official docs](https://developers.google.com/admob/android/impression-level-ad-revenue)\n\n```kotlin\nvar rewardedAd: RewardedAd? = null\nval adRequest = AdRequest.Builder().build()\nRewardedAd.load(this,\"AD_UNIT_ID\", adRequest, object : RewardedAdLoadCallback() {\n    override fun onAdLoaded(ad: RewardedAd) {\n        rewardedAd = ad\n        // Set paid event listener\n        rewardedAd.onPaidEventListener = OnPaidEventListener { adValue -\u003e\n            val loadedAdapterResponseInfo = ad.responseInfo.loadedAdapterResponse\n\n            // Send AdRevenue info\n            AffiseAdRevenue(AffiseAdSource.ADMOB)\n                .setRevenue(adValue.valueMicros / 1000000, adValue.currencyCode)\n                .setNetwork(loadedAdapterResponseInfo.adSourceName)\n                .setUnit(ad.adUnitId)\n                .send()\n        }\n    }\n})\n```\n\n## AppLovin MAX\n\nFor more information how to setup, please check [official docs](https://dash.applovin.com/documentation/mediation/android/getting-started/advanced-settings)\n\n```kotlin\noverride fun onAdRevenuePaid(ad: MaxAd)\n{\n    // Send AdRevenue info\n    AffiseAdRevenue(AffiseAdSource.APPLOVIN_MAX)\n      .setRevenue(ad.revenue, \"USD\")\n      .setNetwork(ad.networkName)\n      .setUnit(ad.adUnitId)\n      .setPlacement(ad.placement)\n      .send()\n}\n```\n\n## Helium by Chartboost\n\nFor more information how to setup, please check [official docs](https://developers.chartboost.com/docs/mediation-android-configure-helium#implementation)\n\n```kotlin\nval ilrdObserver = object: HeliumIlrdObserver {\n    override fun onImpression(impData: HeliumImpressionData) {\n        val json: JSONObject = impData.ilrdInfo\n\n        val revenue = json.getDouble(\"ad_revenue\")\n        val currency = json.getString(\"currency_type\")\n\n        // Send AdRevenue info\n        AffiseAdRevenue(AffiseAdSource.HELIUM_CHARTBOOST)\n            .setRevenue(revenue, currency)\n            .setNetwork(json.optString(\"network_name\"))\n            .setUnit(json.optString(\"placement_name\"))\n            .setPlacement(json.optString(\"line_item_name\"))\n            .send()\n    }\n}\n```\n\n## ironSource\n\nFor more information how to setup, please check [official docs](https://developers.is.com/ironsource-mobile/android/ad-revenue-measurement-integration/#step-2)\n\n```kotlin\nfun onImpressionSuccess(impressionData: ImpressionData) {\n    // Send AdRevenue info\n    AffiseAdRevenue(AffiseAdSource.IRONSOURCE)\n        .setRevenue(impressionData.revenue, \"USD\")\n        .setNetwork(impressionData.adNetwork)\n        .setUnit(impressionData.adUnit)\n        .setPlacement(impressionData.placement)\n        .send()\n}\n```\n\n## Admost\n\nFor more information how to setup, please check [official docs](https://admost.github.io/amrandroid/)\n\n```kotlin\nfun onAdRevenuePaid(impressionData: AdMostImpressionData) {\n    // Send AdRevenue info\n    AffiseAdRevenue(AffiseAdSource.ADMOST)\n        .setRevenue(impressionData.Revenue, impressionData.Currency)\n        .setNetwork(impressionData.Network)\n        .setUnit(impressionData.AdUnitId)\n        .setPlacement(impressionData.PlacementId)\n        .send()\n}\n```\n\n# Debug\n\n## Validate credentials\n\n\u003e **Warning**\n\u003e \n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\u003e \n\u003e Debug methods WON'T work on Production\n\u003e\n\u003e 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥\n\nValidate your credentials by receiving `ValidationStatus` values:\n\n- `VALID` - your credentials are valid\n- `INVALID_APP_ID` - your app id is not valid\n- `INVALID_SECRET_KEY` - your SDK secretKey is not valid\n- `PACKAGE_NAME_NOT_FOUND` - your application package name not found\n- `NOT_WORKING_ON_PRODUCTION` - you using debug method on production\n- `NETWORK_ERROR` - network or server not available (for example `Airoplane mode` is active)\n\n```kotlin\nAffise\n  .settings(\n    affiseAppId = \"Your appId\",\n    secretKey = \"Your SDK secretKey\"\n  )\n  .setProduction(false) //To enable debug methods set Production to false\n  .start(this) // Start Affise SDK\n\nAffise.Debug.validate { status -\u003e\n    // Handle validation status\n}\n```\n\n\n## Version\n\nGet Affise library version\n\n```kotlin\nAffise.Debug.version()\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faffise%2Fsdk-android","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faffise%2Fsdk-android","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faffise%2Fsdk-android/lists"}