# Android v2.1.X

### Introduction

#### SDK overview

Welcome to the Flagship Android SDK documentation!

The following article will guide you through the steps to get Flagship up and running on your native Android app using our client library with preconfigured methods to implement the Decision API.

Feel free to [contact us](mailto:product.feedback@abtasty.com?subject=Flagship%20Developer%20Documentation) if you have any questions regarding this documentation.

#### Release notes

[See here](doc:android-sdk)

#### SDK features

This SDK version will help you:

* Set a [visitor ID](doc:glossary)
* Update [user context](doc:glossary.)
* Assign campaigns via the [Decision API](doc:decision-api) or [Bucketing](doc:bucketing)
* Get modifications
* Activate campaigns
* Send hits to our [Universal Collect](doc:universal-collect-documentation)

#### Prerequisites

* Your app must be a native Android app written in Kotlin or Java
* Your app must at least be compatible with Android API version 21 (Android 5.0) **OR** version 16 (Android 4.1) if you use the compatibility version of our library. [See dependencies](#dependency)

  > The `minSdkVersion` value in your app module's build.gradle file must be greater than or equal to **21**:

```groovy
android {
    compileSdkVersion 28
    defaultConfig {
        minSdkVersion 21
        ...
    }
}
```

* Your app must have the necessary permissions to use the Internet

  > Internet permission must be enabled in the \<application> tag of your app's AndroidManifest.xml file:

```xml
<?xml version="1.0" encoding="utf-8"?>
<manifest>
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- [...] -->
</manifest>
```

* Your app must have AndroidX enabled

#### Good to know

* [GitHub repository](https://github.com/flagship-io/flagship-android)
* Weight: 112ko
* Kotlin and Java code supported
* [Open source demo app](https://github.com/abtasty/flagship-demo-android)

### Getting Started

#### Installation

To install the library, start by adding the following repository in the **main build.gradle** file of your Android project so that Gradle can find and build with the library:

`https://abtasty.jfrog.io/artifactory/flagship-android/`

```groovy
allprojects {
    repositories {
        maven {
            url 'https://abtasty.jfrog.io/artifactory/flagship-android/'
        }
    }
}
```

Then add the following library dependency in the **build.gradle** file of your **app module**:

**`com.abtasty:flagship-android:x.x.x`**

> 📘 Replace `x.x.x` with the desired version of the Flagship SDK.

```groovy
dependencies {
    implementation 'com.abtasty:flagship-android:2.1.0'
}
```

> 🚧 If you need to target Android versions from Android 4.1+ API level 16+, use the following code, starting at version 1.2.1 of the Flagship Android SDK:
>
> **`com.abtasty:flagship-android-compat:x.x.x`**
>
> Available from the maven repository url:
>
> [**https://abtasty.jfrog.io/artifactory/flagship-android-compat/**](https://abtasty.jfrog.io/artifactory/flagship-android-compat/)
>
> This version ensures TLS 1.2 compatibility between our servers and Android 4.1+, but we do not recommand using it due to lack of TLS 1.2 support by these platforms.

#### Initialization

To initialize and start the library, just call the `init` function of the `Flagship` class, and call the `start` method from the returned Builder in the most appropriate location for your application.

```kotlin
class MyActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Flagship.builder(applicationContext, "my_env_id", "my_api_key").start()
    }
}
```

```java
public class MyActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Flagship.Companion.builder(getApplicationContext(), "my_env_id", "my_api_key").start();
    }
}
```

**`fun builder(appContext: Context, envId: String, apiKey : String) : Builder`**

| Parameter | Type    | Description                                  |
| --------- | ------- | -------------------------------------------- |
| context   | Context | Android application context of your app.     |
| envId     | String  | Environment id provided by Flagship.         |
| apiKey    | String  | Api authentication key provided by Flagship. |

> 📘
>
> You can find your `apiKey` and your `environmentId` on your Flagship account, in Parameters > Environment & Security.

**Builder Instance**

The previous function returns the main Builder that initializes the library.

```kotlin
Flagship.builder(applicationContext, "my_env_id", "my_api_key")
    .withFlagshipMode(Flagship.Mode.BUCKETING)
    .withLogEnabled(Flagship.LogMode.ALL)
    .withVisitorId("my_visitor_id)
    .withVisitorConsent(true)
    .withReadyCallback {
        Hit.Event(Hit.EventCategory.ACTION_TRACKING, "sdk-android-ready").send()
        runOnUiThread { update() }
    }
    .start()
```

```java
Flagship.Companion.builder(this.getApplicationContext(), "my_env_id", "my_api_key")
    .withFlagshipMode(Flagship.Mode.BUCKETING)
    .withLogEnabled(Flagship.LogMode.ALL)
    .withVisitorId("my_visitor_id")
    .withVisitorConsent(true)
    .withReadyCallback(() -> {
        new Hit.Event(Hit.EventCategory.ACTION_TRACKING, "sdk-android-ready").send();
        MainJava.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                updateView();
            }
        });
        return null;
    })
    .start();
```

The Builder instance helps you to configure and initialize the SDK via the following optional methods:

* **`fun withFlagshipMode(mode: Mode): Builder`**

  This method lets you start the Flagship SDK in `BUCKETING` mode (decision logic is executed client-side) or `DECISION_API` mode (decision logic is executed server-side). The decision mode is set to `DECISION_API` by default. [**Learn more**](#decision-mode)

  | Parameter | Type | Description                              |
  | --------- | ---- | ---------------------------------------- |
  | mode      | Mode | `DECISION_API` (default) or `BUCKETING`. |
* **`fun withReadyCallback(lambda: (() -> Unit)): Builder`**

  This method lets you define code that should run after the SDK is done initializing (e.g. sending an `sdk-android-ready` [event hit](doc:universal-collect-documentation#event)).

  | Parameter | Type         | Description                                                  |
  | --------- | ------------ | ------------------------------------------------------------ |
  | lambda    | (() -> Unit) | Lambda to be called when the SDK inizialization is complete. |
* **`fun withVisitorId(visitorId: String): Builder`**

  This method lets you identify the current visitor.

  | Parameter       | Type                  | Description                                                                                                                                                                                          |
  | --------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | visitorId       | String?               | Unique identifier for the current user. This can be an ID from your database or a session ID. If no value is passed, the SDK will automatically generate a unique ID. [**Learn more**](doc:glossary) |
  | isAuthenticated | Boolean               | Specify if the current visitor is authenticated (true) or is anonymous (false). False by default.                                                                                                    |
  | visitorContext  | HashMap\<String, Any> | Current visitor context properties. Keys must be String, and Values must be Number, String, or Boolean.                                                                                              |
* **`fun withVisitorConsent(consent: Boolean): Builder`**

  Specify if the visitor has consented to personal data usage. When false some features will be deactivated, the the cache will be deactivated and cleared. Default value is True.

  | Parameter | Type    | Description                                                          |
  | --------- | ------- | -------------------------------------------------------------------- |
  | consent   | Boolean | True when user has given consent, false otherwise. (true by default) |
* **`fun withLogEnabled(mode: LogMode): Builder`**

  This method lets you enable SDK logs and configure

  | Parameter | Type    | Description                                                         |
  | --------- | ------- | ------------------------------------------------------------------- |
  | mode      | LogMode | Type of log to display. [**Learn more**](doc:glossary#sdk-log-mode) |
* **`fun withTimeout(timeout : Long, timeUnit: TimeUnit): Builder`**

  Initialize the SDK with a campaign request timeout. Default is 2 seconds.

  | Parameter | Type     | Description      |
  | --------- | -------- | ---------------- |
  | timeout   | Long     | Timeout duration |
  | timeUnit  | TimeUnit | Duration Unit    |
* **`fun start()`**

  This method lets you build and start the Flagship SDK.

> 🚧 The SDK gives you the ability to change the `envId` for QA purposes. Don't forget to **delete your app cache** when changing environments.

**Decision Mode**

**`DECISION_API`Mode**

When the SDK is running in `DECISION_API` mode, the campaign assignments and targeting validation take place server-side. In this mode, each call to the `synchronizeModifications` method to refresh the modifications will create an HTTP request.

**`BUCKETING`Mode**

When the SDK is running in `BUCKETING` mode, the SDK downloads all the campaigns configurations at once in a single bucketing file so that variation assignment can be computed client-side by the SDK. This bucketing file is stored in the the cache and will only be downloaded again when campaign configurations are modified in the Flagship interface. [**Learn more**](doc:bucketing)

### Updating the user context

The user context is a property dataset that defines the current user of your app. This dataset is sent and used by the Flagship Decision API as targeting criteria for campaign assignment.

For example, if you wanted to enable or disable a specific feature based on VIP status, you would pass that attribute as a key-value pair in the user context so that the Decision API can enable or disable the corresponding feature flag for the user.

> 📘 User context values are used for targeting configuration.

```kotlin
Flagship.updateContext("vipUser", vipUser)
Flagship.updateContext("age", age) {
    this@MainActivity.runOnUiThread { applyChanges() }
}
```

```java
Flagship.Companion.updateContext("vipUser", currentVisitor.vip);
Flagship.Companion.updateContext("age", currentVisitor.age, () -> {
    MainJava.this.runOnUiThread(this::applyChanges);
    return null;
});
```

The SDK provides a set of methods to push new user context values to Flagship.

These functions update the user context value matching the given key. If there isn't an existing value matching that key, a new context value associated with this key will be created.

* Add a Int, Float, Long, Double Value to the user context:

  **`fun updateContext(key: String, value: Number, sync: (() -> (Unit))? = null)`**
* Add a String Value to the user context:

  **`fun updateContext(key: String, value: String, sync: (() -> (Unit))? = null)`**
* Add a Boolean Value to the user context:

  **`fun updateContext(key: String, value: Boolean, sync: (() -> (Unit))? = null)`**
* Add a HashMap Value to the user context:

  **`fun updateContext(values: HashMap<String, Any>, sync: (() -> (Unit))? = null)`**
* Add a PresetContext Value to the user context:

  **`fun updateContext(key: PresetContext, value: Any, sync: (() -> (Unit))? = null)`**

| Parameter | Type                    | Description                                                                                                                                                                                                                                                                                                                                                      |
| --------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| key       | String                  | Attribute key associated with the following value                                                                                                                                                                                                                                                                                                                |
| value     | String, Number, Boolean | Attribute value to add in the context                                                                                                                                                                                                                                                                                                                            |
| sync      | sync: (() -> (Unit))?   | Optional. Default value is `null`. Passing a lambda as a parameter will automatically call `synchronizeModifications()` and apply the modifications from the server to all campaigns with the updated current context. The given lambda will be invoked when finished. You can also update it manually: [`synchronizeModifications()`](#synchronizing-campaigns) |

> 🚧 User context values must have a type of **string**, **number**, or **boolean** to be accepted by Flagship.

#### Retrieve current visitor context

Use the following method to get the current visitor context key values:

**`fun getContext() : fun getContext(): HashMap<String, Any>`**

```kotlin
val visitorContext = Flagship.getContext()
```

```java
Flagship.Companion.getContext();
```

#### Predefined visitor context keys

The Flagship SDK contains predefined user context keys that do not count against your plan quota. Some of the predefined keys will automatically set their values, but you can always override them if needed. These key-value pairs are sent to Flagship and are available in the "Persona" section of the Flagship interface.

For a full list of the predefined keys, [see the appendix](#appendix).

### Campaign synchronization

#### Synchronizing campaigns

Synchronizing campaign modifications allows you to automatically call the Flagship Decision API or bucketing file to run assignments in accordance with the user context to get all their modifications.

All the applicable modifications are stored in the SDK and are updated asynchronously when `synchronizeModifications()` is called.

```kotlin
Flagship.synchronizeModifications {
    this@MainActivity.runOnUiThread { applyChanges() }
}
```

```java
Flagship.Companion.synchronizeModifications( () -> {
    MainJava.this.runOnUiThread(this::applyChanges);
    return null;
    });
```

**`fun synchronizeModifications(callback: (() -> (Unit))? = null)`**

| Parameter | Type         | Description                                                                                |
| --------- | ------------ | ------------------------------------------------------------------------------------------ |
| callback  | () -> (Unit) | Lambda to be invoked when the SDK has finished updating the modifications from the server. |

#### Getting modifications

Once the campaign has been **assigned** and **synchronized**, all the modifications are stored in the SDK. You can retrieve these modifications using the following functions:

```kotlin
val color = Flagship.getModification("btnColor", "#0e5fe3")
button.setBackgroundColor(Color.parseColor(color))
```

```java
String color = Flagship.Companion.getModification("btnColor", "#FFFFFF");
button.setBackgroundColor(Color.parseColor(color));
```

* Get Modification for Double value:

  **`fun getModification(key: String, default: Double, activate: Boolean = false): Double`**
* Get Modification for Int value:

  **`fun getModification(key: String, default: Int, activate: Boolean = false): Int`**
* Get Modification for Long value:

  **`fun getModification(key: String, default: Long, activate: Boolean = false): Long`**
* Get Modification for Float value:

  **`fun getModification(key: String, default: Float, activate: Boolean = false): Float`**
* Get Modification for String value:

  **`fun getModification(key: String, default: String, activate: Boolean = false): String`**
* Get Modification for Boolean value:

  **`fun getModification(key: String, default: Boolean, activate: Boolean = false): Boolean`**
* Get Modification for JSONObject value:

  **`fun getModification(key: String, default: JSONObject, activate: Boolean = false): JSONObject`**
* Get Modification for JSONArray value:

  **`fun getModification(key: String, default: JSONArray, activate: Boolean = false): JSONArray`**

| Parameter | Type                                                       | Description                                                                                                                                                                                                                                  |
| --------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| key       | String                                                     | Key associated with the modification.                                                                                                                                                                                                        |
| default   | String, Boolean, Int, Float, Double, JSONArray, JSONObject | The default value if no value for this modification is found.                                                                                                                                                                                |
| activate  | Boolean                                                    | Optional. Set to `False` by default. Set this parameter to `True` to automatically report on our server that the current visitor has seen this modification. If `False`, call the [activateModification()](#activating-modifications) later. |

#### Getting campaign information

You may need to send campaign IDs to a third-party for reporting and/or analytics purposes. It is now possible to retrieve campaigns IDs for a specific modification key.

```kotlin
Flagship.getModificationInfo("modification_key")
```

```java
Flagship.Companion.getModificationInfo("modification_key")
```

**`fun getModificationInfo(key: String) : JSONObject?`**

| Parameter | Type   | Description                           |
| --------- | ------ | ------------------------------------- |
| key       | String | Key associated with the modification. |

It returns a JSONObject? containing `campaignId`, `variationGroupId`, `variationId` and `isReference` keys & values or null if the modification is not found (the user is not affected to the campaign linked to the modification).

#### Activating modifications

Once a modification has been rendered on the screen for a user, you must send an activation event to tell Flagship that the user has seen this specific variation.

```kotlin
val color = Flagship.getModification("btnColor", "#0e5fe3", true)
button.setBackgroundColor(Color.parseColor(color))

//---OR---

Flagship.activateModification("btnColor")
```

```java
String color = Flagship.Companion.getModification("btnColor", "#FFFFFF", true);
button.setBackgroundColor(Color.parseColor(color));
Flagship.Companion.activateModification("btnColor");
```

**`fun activateModification(key: String)`**

| Parameter | Type   | Description                           |
| --------- | ------ | ------------------------------------- |
| key       | String | Key associated with the modification. |

### Managing visitor consent

The Visitor class provides a method to let you manage visitor consent for data privacy usage. When False, ***campaign activation*** and ***hits*** will be disabled and cache cleared.

**`fun setConsent(hasConsented : Boolean)`**

| Parameter    | Type    | Description                                                                                                                                        |
| ------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| hasConsented | Boolean | Set visitor consent for private data usage. When false some features will be deactivated, cache will be deactivated and cleared. (true by default) |

```kotlin
//when the visitor hadn't given consent
Flagship.setConsent(false)

//when the visitor gives consent
Flagship.setConsent(true)
```

```java
//when the visitor hadn't given consent
Flagship.Companion.setConsent(false)

//when the visitor gives consent
Flagship.Companion.setConsent(true)
```

### Experience Continuity

In some situations, you may want experience consistency between an anonymous visitor and an authenticated visitor. Flagship provides the following two methods in order to help you to specify when a visitor is authenticated or not.\
[Learn more](doc:experience-continuity)

#### Authenticate

**`fun authenticateVisitor(visitorId: String, visitorContext: HashMap<String, Any>? = null, sync: (() -> Unit)? = null)`**

| Parameter      | Type                   | Description                                                                                                                                                                                                                                                            |
| -------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| visitorId      | String                 | id of the new authenticated visitor.                                                                                                                                                                                                                                   |
| visitorContext | HashMap\<String, Any>? | (optional: null by default) Replace the current visitor context. Passing null won't replace context and will ensure consistency with the previous visitor context.                                                                                                     |
| sync           | lambda                 | (optional: null by default) If lambda is passed as a a parameter: it will automatically update the campaign's modifications. Then this lambda will be invoked when finished. You also have the possibility to update it manually by calling synchronizeModifications() |

#### Unauthenticate

**`fun unauthenticateVisitor(visitorContext: HashMap<String, Any>? = null, sync: (() -> Unit)? = null)`**

| Parameter      | Type                   | Description                                                                                                                                                                                                                                                            |
| -------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| visitorContext | HashMap\<String, Any>? | (optional: null by default) Replace the current visitor context. Passing null won't replace context and will ensure consistency with the previous visitor context.                                                                                                     |
| sync           | lambda                 | (optional: null by default) If lambda is passed as a a parameter: it will automatically update the campaign's modifications. Then this lambda will be invoked when finished. You also have the possibility to update it manually by calling synchronizeModifications() |

#### Code example

```kotlin
//When user log in
Flagship.authenticateVisitor("new_visitor_id")


//when user log out
Flagship.unauthenticateVisitor()
```

```java
//When user log in
Flagship.Companion.authenticateVisitor("new_visitor_id")


//when user log out
Flagship.Companion.unauthenticateVisitor()
```

### Hit Tracking

This section helps send tracking and learn how to build hits in order to approve campaign goals. For more information about our measurement protocol, read our [Universal Collect documentation](doc:universal-collect-documentation).

There are four different types of Hits available:

* Screen
* Transaction
* Item
* Event

**They must all be built and sent with the following function:**

**`fun <T> sendHit(hit: HitBuilder<T>)`**

#### Common Parameters

These parameters can be sent with any type of hit.

| Parameter               | Type   | Description                         |
| ----------------------- | ------ | ----------------------------------- |
| userIp                  | String | Optional. User IP                   |
| screenResolution        | String | Optional. Screen Resolution.        |
| userLanguage            | String | Optional. User Language             |
| currentSessionTimeStamp | Int64  | Optional. Current Session Timestamp |
| sessionNumber           | Int    | Optional. Session Number            |

#### Screen

This hit should be sent each time a visitor arrives on a new interface.

```kotlin
Flagship.sendHit(Hit.Screen("MainActivity"))
```

```java
Flagship.Companion.sendHit(
  new Hit.Screen("MainActivity")
);
```

**`class Screen(origin: String) : HitBuilder<Screen>()`**

| Builder Parameter | Type   | Description            |
| ----------------- | ------ | ---------------------- |
| location          | String | Name of the interface. |

#### Transaction

This hit should be sent when a user completes a transaction.

```kotlin
Flagship.sendHit(Hit.Transaction("#4802982", "mobile_purchases")
    .withCouponCode("#PROMO")
    .withCurrency("EUR")
    .withItemCount(1)
    .withPaymentMethod("credit_card")
    .withShippingCost(2.99f)
    .withShippingMethod("express")
    .withTaxes(15.47f)
    .withTotalRevenue(279f)
)
```

```java
Flagship.Companion.sendHit(new Hit.Transaction("#4802982", "mobile_purchases")
                .withCouponCode("#PROMO")
                .withCurrency("EUR")
                .withItemCount(1)
                .withPaymentMethod("credit_card")
                .withShippingCost(2.99f)
                .withShippingMethod("express")
                .withTaxes(15.47f)
                .withTotalRevenue(279f)
        );
```

**`class Transaction(transactionId: String, affiliation: String) : HitBuilder<Transaction>()`**

| Builder Parameter  | Type   | Description                                                                                                                       |
| ------------------ | ------ | --------------------------------------------------------------------------------------------------------------------------------- |
| transactionId      | String | Unique identifier for your transaction.                                                                                           |
| affiliation        | String | The name of the KPI that you will have inside your reporting. [**Learn more**](doc:glossary#kpi)                                  |
| totalRevenue       | Float  | Optional. Specifies the total revenue associated with the transaction. This value should include any shipping and/or tax amounts. |
| shippingCost       | Float  | Optional. The total shipping cost of your transaction.                                                                            |
| withShippingMethod | String | Optional. The shipping method for your transaction.                                                                               |
| taxes              | Float  | Optional. Specifies the total amount of taxes in your transaction.                                                                |
| currency           | String | Optional. Specifies the currency of your transaction. NOTE: This value should be a valid ISO 4217 currency code.                  |
| paymentMethod      | String | Optional. Specifies the payment method used for your transaction.                                                                 |
| itemCount          | Int    | Optional. Specifies the number of items in your transaction.                                                                      |
| couponCode         | String | Optional. Specifies the coupon code used by the customer in your transaction.                                                     |

#### Item

This hit is used to link an item with a transaction. It must be sent after the corresponding transaction hit.

```kotlin
Flagship.sendHit(Hit.Item("#4802982", "N_SWITCH_19", "#NS19AHLD")
    .withItemCategory("video_games")
    .withItemQuantity(1)
    .withPrice(279f)
)
```

```java
Flagship.Companion.sendHit(new Hit.Item("#4802982", "N_SWITCH_19", "#NS19AHLD")
    .withItemCategory("video_games")
    .withItemQuantity(1)
    .withPrice(279f)
)
```

**`class Item(transactionId: String, productName: String, productSku : String) : HitBuilder<Item>()`**

| Builder Parameter | Type   | Description                                                |
| ----------------- | ------ | ---------------------------------------------------------- |
| transactionId     | String | Unique identifier for your transaction.                    |
| product name      | String | The name of your item.                                     |
| productSku        | String | Specifies the SKU or item code.                            |
| price             | Float  | Optional. Specifies the price for a single item/unit.      |
| itemCategory      | String | Optional. Specifies the category that the item belongs to. |
| itemQuantity      | Int    | Optional. Specifies the number of items purchased.         |

> 📘 The `Item` hit isn't available yet in the Flagship [reporting view](https://flagship.zendesk.com/hc/en-us/articles/360014662280-Reporting-Filters).

#### Event

This hit can be used for any event (e.g. Add To Cart click, newsletter subscription).

```kotlin
Flagship.sendHit(Hit.Event(Hit.EventCategory.ACTION_TRACKING, "click")
    .withEventLabel("button_click")
    .withEventValue(12)
)
```

```java
Flagship.Companion.sendHit(new Hit.Event(Hit.EventCategory.ACTION_TRACKING, "click")
                .withEventLabel("button_click")
                .withEventValue(12));
```

**`class Event(category: EventCategory, action: String) : HitBuilder<Event>()`**

| Builder Parameter | Type          | Description                                                                                                                                                                        |
| ----------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| category          | EventCategory | Event category of the event (`ACTION_TRACKING` or `USER_ENGAGEMENT`).                                                                                                              |
| action            | String        | Event name that will also serve as the KPI that you will have inside your reporting. [**Learn more**](doc:glossary#kpi)                                                            |
| label             | String        | Optional. Additional description of your event.                                                                                                                                    |
| value             | Number        | Optional. Specifies the monetary value associated with an event (e.g. you earn 10 to 100 euros depending on the quality of lead generated). NOTE: this value must be non-negative. |

### Appendix

#### Predefined user context keys

The Flagship SDK contains predefined user context keys.

The keys marked as **Yes** in the **Auto-set by SDK** column will be automatically set, while the ones marked as **No** need to be set by the client.

> 📘 Check the values sent by the SDK by enabling the logs.

You can overwrite these keys at any time. The key-value pairs will be sent to the server in the user context and can be edited in the [Persona](doc:glossary#persona) section of the Flagship platform.

| SDK Variable Name              | Description                                            | Context variable name                 | Type    | Auto-set by SDK | Example                                      |
| ------------------------------ | ------------------------------------------------------ | ------------------------------------- | ------- | --------------- | -------------------------------------------- |
| FIRST\_TIME\_INIT              | First init of the app                                  | sdk\_firstTimeInit                    | Boolean | Yes             | TRUE (FALSE if the init isn't the first one) |
| LOCALE                         | Language of the device                                 | sdk\_deviceLanguage                   | String  | Yes             | fr\_FR                                       |
| DEVICE\_TYPE                   | Tablette / Mobile                                      | sdk\_deviceType                       | String  | Yes             | mobile                                       |
| DEVICE\_MODEL                  | Model of the device                                    | sdk\_deviceModel                      | String  | Yes             | samsung E1200                                |
| LOCATION\_CITY                 | City geolocation                                       | sdk\_city                             | String  | No              | toulouse                                     |
| LOCATION\_REGION               | Region geolocation                                     | sdk\_region                           | String  | No              | occitanie                                    |
| LOCATION\_COUNTRY              | Country geolocation                                    | sdk\_country                          | String  | No              | France                                       |
| LOCATION\_LAT                  | Current Latitude                                       | sdk\_lat                              | Double  | No              | 43.623647                                    |
| LOCATION\_LONG                 | Current Longitude                                      | sdk\_long                             | Double  | No              | 1.445397                                     |
| IP                             | IP of the device                                       | sdk\_ip                               | String  | No              | 127.0.0.1                                    |
| OS\_NAME                       | Name of the OS                                         | sdk\_osName                           | String  | Yes             | android / iOS                                |
| OS\_VERSION                    | Version of the OS                                      | sdk\_osVersion                        | String  | Yes             | pie                                          |
| API\_LEVEL                     | Version of the API                                     | sdk\_apiLevel                         | Integer | Yes             | 24                                           |
| ANDROID\_VERSION / IOS VERSION | Version of Android                                     | sdk\_androidVersion / sdk\_iOSVersion | String  | Yes             | 9                                            |
| MVNO / carrierName             | Name of the carrier or mobile virtual network operator | sdk\_carrierName                      | String  | Yes             | orange                                       |
| DEV\_MODE                      | Is the app in debug mode?                              | sdk\_devMode                          | Boolean | Yes             | TRUE                                         |
| VISITOR\_ID                    | Visitor\_id of the user                                | sdk\_visitorId                        | String  | Yes             | toto2000                                     |
| INTERNET\_CONNECTION           | What is the internet connection                        | sdk\_internetConnection               | String  | No              | 3g                                           |
| APP\_VERSION\_NAME             | Version name of the app                                | sdk\_versionName                      | String  | No              | 1.1.2-beta                                   |
| APP\_VERSION\_CODE             | Version code of the app                                | sdk\_versionCode                      | Integer | No              | 40                                           |
| FLAGSHIP\_VERSION              | Version of the Flagship SDK                            | sdk\_fsVersion                        | String  | Yes             | 1.1.2                                        |
| INTERFACE\_NAME                | Name of the interface                                  | sdk\_interfaceName                    | String  | No              | ProductPage                                  |

> 📘 To overwrite the keys, use the [`updateContext`](#update-context-with-predefined-keys-of-context) method
