Android v2.0.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 if you have any questions regarding this documentation.

Release notes

See here

SDK features

This SDK version will help you:

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 compatibilty version of our library. See dependencies

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

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:

<uses-permission android:name="android.permission.INTERNET" />
  • Your app must have AndroidX enabled

Good to know

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/

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

dependencies {
	implementation 'com.abtasty:flagship-android:2.0.3'
}

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

Compatibilty with Android 4.1

If you need to target Android versions from Android 4.1+ API level 16+, use the following library and repository, starting at version 1.2.1 of the Flagship Android SDK:

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

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

com.abtasty:flagship-android-compat:x.x.x

dependencies {
	implementation 'com.abtasty:flagship-android-compat:2.0.3'
}

❗️

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.

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

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

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

Parameter
Type
Description

context

Context

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.

Flagship.builder(applicationContext, "my_env_id", "my_api_key")

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

                .withFlagshipMode(Flagship.Mode.BUCKETING)
                .withLogEnabled(Flagship.LogMode.ALL)
                .withVisitorId("my_visitor_id")
                .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

    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).

    Parameter
    Type
    Description

    lambda

    (() -> Unit)

    Lambda to be called when the SDK inizialization is complete.

  • fun withVisitorId(visitorId: String): Builder

    This method lets you set the unique identifier the current user.

    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

  • 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

  • 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 withVisitorContext(visitorContext: HashMap<String, Any>): Builder

    Initialize the SDK with this visitor context key values.

    Parameter
    Type
    Description

    visitorContext

    HashMap<String, Any>

    Keys must be String, and Values must be Number, String, or Boolean.

  • 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_APIMode

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.

BUCKETINGMode

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 cache and will only be downloaded again when campaign configurations are modified in the Flagship interface. Learn more

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 campaign targeting configuration.

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

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()

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

Predefined user 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.

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.

Flagship.Companion.synchronizeModifications( () -> {
    MainJava.this.runOnUiThread(this::applyChanges);
    return null;
    });
Flagship.synchronizeModifications {
    [email protected] { applyChanges() }
}

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

Parameter
Type
Description

callback

() -> (Unit)

Lambda to be invoked when the SDK has finished to update 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:

String color = Flagship.Companion.getModification("btnColor", "#FFFFFF");
button.setBackgroundColor(Color.parseColor(color));
val color = Flagship.getModification("btnColor", "#0e5fe3")
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() 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.

Flagship.Companion.getModificationInfo("modification_key")
Flagship.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.

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

Flagship.Companion.activateModification("btnColor");
val color = Flagship.getModification("btnColor", "#0e5fe3", true)
button.setBackgroundColor(Color.parseColor(color))

  ---OR---

Flagship.activateModification("btnColor")

fun activateModification(key: String)

Parameter
Type
Description

key

String

Key associated with the modification.

Hit Tracking

This section helps send tracking and learn how to build hits in order to aprove campaign goals. For more information about our measurement protocol, read our 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.

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

class Screen(location: 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.

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)
        );
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)
            )

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

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.

Flagship.Companion.sendHit(new Hit.Item("#4802982", "N_SWITCH_19", "#NS19AHLD")
               .withItemCategory("video_games")
               .withItemQuantity(1)
               .withPrice(279f));
Flagship.sendHit(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.

Event

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

Flagship.Companion.sendHit(new Hit.Event(Hit.EventCategory.ACTION_TRACKING, "click")
                .withEventLabel("button_click")
                .withEventValue(12));
Flagship.sendHit(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

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 keys-value pairs will be sent to the server in the user context and can be edited in the 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 method

Coucou

// Some code

Last updated

Was this helpful?