# Setup

Follow these steps to setup the Didomi Android and Android TV SDK:

* [Requirements](#requirements)
* [Add the SDK to your project](#add-the-sdk-to-your-project)
* [Initialize the SDK](#initialize-the-sdk)
* [Setup the SDK UI](#setup-the-sdk-ui)
* [Configure the SDK](#configure-the-sdk)

## Requirements

We offer our SDK as a pre-compiled package that you can add to your application. We support SDK versions >= 21 (`minSdkVersion(21)`) and its target/compile version is the [minimum required for Google Play](https://developer.android.com/distribute/best-practices/develop/target-sdk).

## Add the SDK to your project

The package is distributed through the mavenCentral repository. Make sure it is added to your repositories in your project `build.gradle` file:

{% tabs %}
{% tab title="build.gradle" %}

```groovy
buildscript {
    repositories {
        mavenCentral()
    }
}
```

{% endtab %}
{% endtabs %}

Add our SDK to your dependencies:

{% tabs %}
{% tab title="build.gradle" %}

```
dependencies {
    implementation 'io.didomi.sdk:android:2.39.0'
}
```

{% endtab %}
{% endtabs %}

Our SDK requires permissions to use the Internet connection and check its status so the following permissions will be merged to your `AndroidManifest` file:

{% tabs %}
{% tab title="AndroidManifest.xml" %}

```markup
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.my.app">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
```

{% endtab %}
{% endtabs %}

## Initialize the SDK

Once our SDK has been added to your project, you need to initialize it. The initialization process will run in a background thread and prepare the SDK for interactions with the user and your application. It is important to launch the SDK initialization as soon as possible.

In the `onCreate` function of your main `Application` class, call the `Didomi.getInstance().initialize` function and pass a reference to your `Application` instance and your API key:

{% tabs %}
{% tab title="Java" %}

```java
package com.my.app;

import android.app.MultiDexApplication;
import android.util.Log;

import io.didomi.sdk.Didomi;

public class SampleApplication extends MultiDexApplication {
    @Override
    public void onCreate() {
        super.onCreate();

        try {
            Didomi.getInstance().initialize(
                this,
                new DidomiInitializeParameters(
                    /*apiKey*/ "<Your API key>",
                    /*localConfigurationPath*/ "<Your local config path>",
                    /*remoteConfigurationURL*/ "<Your remote config url>",
                    /*providerID*/ "<Your provider ID>",
                    /*disableDidomiRemoteConfig*/ true|false,
                    /*languageCode*/ "<Your language code>",
                    /*noticeID*/ "<Your notice ID>",
                    /*tvNoticeId*/ "<Your TV notice ID>",
                    /*androidTvEnabled*/ true|false
                )
            );
            
            // Do not use the Didomi.getInstance() object here for anything else than registering your ready listener
            // The SDK might not be ready yet
            
            Didomi.getInstance().onReady(() -> {
                // The SDK is ready, you can now interact with it
            });
        } catch(Exception e) {
            Log.e("App", "Error while initializing the Didomi SDK", e);
        }
    }
}


```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
package com.my.app

import android.util.Log
import androidx.multidex.MultiDexApplication
import io.didomi.sdk.Didomi
import io.didomi.sdk.DidomiInitializeParameters

class SampleApplication : MultiDexApplication() {

    override fun onCreate() {
        super.onCreate()
        try {
            Didomi.getInstance().initialize(
                this,
                DidomiInitializeParameters(
                    apiKey = "<Your API key>",
                    localConfigurationPath = "<Your local config path>",
                    remoteConfigurationURL = "<Your remote config url>",
                    providerID = "<Your provider ID>",
                    disableDidomiRemoteConfig = true|false,
                    languageCode = "<Your language code>",
                    noticeID = "<Your notice ID>",
                    tvNoticeId = "<Your TV notice ID>",
                    androidTvEnabled = true|false
                )
            )
            
            // Do not use the Didomi.getInstance() object here for anything else than registering your ready listener
            // The SDK might not be ready yet
            
            Didomi.getInstance().onReady {
                // The SDK is ready, you can now interact with it
            }
        } catch (e: Exception) {
            Log.e("SampleApp", "Error while initializing the Didomi SDK", e)
        }
    }
}
```

{% endtab %}
{% endtabs %}

It is a good idea to have a try/catch block around the Didomi initialization code and log any error that might happen.

Keep in mind that the SDK initialization is an asynchronous process so you must avoid interacting with the `Didomi` object until it is actually ready to handle your requests. Use the `onReady` function to register a listener for the ready event.

## Setup the SDK UI

{% hint style="info" %}
Note: the setupUI method should be called only from your main/entry `Activities` which in most cases should be once per app launch.

You do not need to call `onReady`, `isReady` or `shouldConsentBeCollected` before calling `setupUI` because they are called internally. Therefore, by calling this method the consent notice and preference views will only be displayed if it is required and only once the SDK is ready.
{% endhint %}

In order for the SDK to be able to display UI elements and interact with the user, you must provide a reference to your main activity. Call the `setupUI` function of the SDK in the `onCreate` lifecycle event of your main activity:

{% tabs %}
{% tab title="Java" %}

```java
package io.didomi.sample;

import android.os.Bundle;
import androidx.fragment.app.FragmentActivity
import io.didomi.sdk.Didomi;

public class SampleActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Didomi.getInstance().setupUI(this);
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
package io.didomi.sample

import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import io.didomi.sdk.Didomi

class SampleActivity : FragmentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        Didomi.getInstance().setupUI(this)
    }
}
```

{% endtab %}
{% endtabs %}

We use the activity to get the fragment manager and register our own lifecycle events. We do not keep a reference to the activity outside of the call to the `setupUI` function to avoid leaks.

{% hint style="warning" %}
For Jetpack compose, you will need to extend `FragmentActivity` instead of `ComponentActivity.`
{% endhint %}

### Deep links

If you are using deep links or have multiple main activities in your app make sure that the `setupUI` function is called on every activity that the user can launch the app on.\
\
This will ensure that consent is always collected as needed and there is no path where the user can launch the app without consent being collected. If `setupUI` is missing at some entry points, you will see lower consent rates as users will be using the app without giving consent.

## Configure the SDK

We support three options for configuration the UI and the behavior of the SDK:

* [Didomi Console](#from-the-console-recommended): the SDK is configured remotely from the Didomi Console
* [Local file](#local-file): the SDK is configured from a `didomi_config.json` file embedded in your app package
* [Remote file](#remote-file): the SDK is configured from a remote `didomi_config.json` file

{% hint style="info" %}
On Android TV / Fire TV, only Didomi Console option is enabled. Local and remote files configuration will be ignored.
{% endhint %}

### From the Console (Recommended)

You can configure the consent notice in your app by creating a notice in your Didomi console. It will automatically be linked to your app through your API key and notice ID. Values for the API key and notice ID can be retrieved directly from the [Didomi console](https://console.didomi.io/).

It is possible to disable this option by setting the `disableDidomiRemoteConfig` parameter to `true` . Default is `false`.

{% tabs %}
{% tab title="Java" %}

```java
Didomi.getInstance().initialize(
    this,
    new DidomiInitializeParameters(
        /*apiKey*/ "<Your API key>",
        /*localConfigurationPath*/ null,
        /*remoteConfigurationURL*/ null,
        /*providerId*/ null,
        /*disableDidomiRemoteConfig*/ false,
        /*noticeID*/ "<Your notice ID>"
    )
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
Didomi.getInstance().initialize(
    this,
    DidomiInitializeParameters(
        apiKey = "<Your API key>",
        localConfigurationPath = null,
        remoteConfigurationURL = null,
        providerId = null,
        disableDidomiRemoteConfig = false,
        noticeID = "<Your notice ID>"
    )
)
```

{% endtab %}
{% endtabs %}

The SDK will automatically use the remote configuration hosted by Didomi and cache it locally. The cached version is refreshed every 60 minutes.

### Local file (deprecated)

{% hint style="danger" %}
Using a local file automatically disables the TCF integration.\
If your app uses the TCF, you must use a configuration from the Didomi Console.
{% endhint %}

{% hint style="warning" %}
Using a local file will prevent you to support multiple regulations.
{% endhint %}

In this option, you create your own SDK configuration file and embed in your app package.

The SDK behavior is configured in a `didomi_config.json` file that must be placed at the root of your `assets/` folder. Create a file with the following content to get started:

{% tabs %}
{% tab title="assets/didomi\_config.json" %}

```javascript
{
    "app": {
        "name": "My App Name",
        "privacyPolicyURL": "http://www.website.com/privacy",
        "vendors": {
            "iab": {
                "all": true
            }
        },
        "gdprAppliesGlobally": true,
        "gdprAppliesWhenUnknown": true
    }
}
```

{% endtab %}
{% endtabs %}

You also need to disable loading the remote configuration to ensure that only the local file is loaded and that no HTTP request is sent. Update your [`initialize`](https://developers.didomi.io/cmp/mobile-sdk/reference/api#initialize) call to set the `disableDidomiRemoteConfig` parameter to `true`:

{% tabs %}
{% tab title="Java" %}

```java
Didomi.getInstance().initialize(
    this,
    new DidomiInitializeParameters(
        /*apiKey*/ "<Your API key>",
        /*localConfigurationPath*/ null,
        /*remoteConfigurationURL*/ null,
        /*providerId*/ null,
        /*disableDidomiRemoteConfig*/ true
    )
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
Didomi.getInstance().initialize(
    this,
    DidomiInitializeParameters(
        apiKey = "<API key>",
        localConfigurationPath = null,
        remoteConfigurationURL = null,
        providerId = null,
        disableDidomiRemoteConfig = true
    )
)
```

{% endtab %}
{% endtabs %}

Your SDK is now setup. [Read the Getting started section](https://developers.didomi.io/cmp/mobile-sdk/consent-notice/getting-started) to learn more about how to configure it to match your app UI and requirements.

### Remote file

{% hint style="danger" %}
Using your own remote file automatically disable the TCF integration.\
If your app uses the TCF, you must use a configuration from the Didomi Console.
{% endhint %}

{% hint style="info" %}
Enabling this option will prevent the configuration from being loaded from the Didomi Console.
{% endhint %}

You can provide a remote URL for the SDK to download the `didomi_config.json` configuration file from. That allows you to update the SDK configuration without having to re-publish you mobile application.

When that configuration is enabled, the SDK will automatically use the remote configuration and cache it locally. The cached version is refreshed every 60 minutes. If there is no connection available to download the remote file and no locally cached version, the SDK will try to use the local `assets/didomi_config.json` as a fallback.

To enable that option, change your call to [initialize](https://developers.didomi.io/cmp/mobile-sdk/reference/api#initialize) to provide the remote file URL:

{% tabs %}
{% tab title="Java" %}

```java
Didomi.getInstance().initialize(
    this,
    new DidomiInitializeParameters(
        /*apiKey*/ "<Your API key>",
        /*localConfigurationPath*/ null,
        /*remoteConfigurationURL*/ "https://www.website.com/didomi_config.json",
        /*providerId*/ null,
        /*disableDidomiRemoteConfig*/ false
    )
);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
Didomi.getInstance().initialize(
    this,
    DidomiInitializeParameters(
        apiKey = "<Your API key>",
        localConfigurationPath = null,
        remoteConfigurationURL = "https://www.website.com/didomi_config.json",
        providerId = null,
        disableDidomiRemoteConfig = false
    )
)
```

{% endtab %}
{% endtabs %}

Also see the [reference documentation of the initialize function](https://developers.didomi.io/cmp/mobile-sdk/reference/api#initialize) for more information.

### Download Global Vendor List (GVL)

Since version 1.28.0 the GVL will be downloaded by default from our API before the SDK is initialized. If you want to stop this behavior, provide the `app.vendors.iab.requireUpdatedGVL` flat set to false in the CUSTOM JSON section when editing your notice on the Console app (or in your local `didomi_config.json` file if that's the case).

```
{
    "app": {
        "vendors": {
            "iab": {
                "requireUpdatedGVL": false
            }
        }
    }
}
```

A timeout can also be provided to specify a maximum timeout for the Download of the GVL. This can be done by providing the `app.vendors.iab.updateGVLTimeout` property (in seconds).

```
{
    "app": {
        "vendors": {
            "iab": {
                "updateGVLTimeout": 10
            }
        }
    }
}
```
