# Step 3: Integration

***

## How to use AppConsent

### 1. Get your AppKey

The first step is to create your source / notice and retrieve your generated **YOUR\_APP\_KEY** from AppConsent :[ https://app.appconsent.io](https://app.appconsent.io)

<figure><img src="https://4229351976-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkyFlZKFaKP4MUM0zILOg%2Fuploads%2F66oLF36aIOado64LfHVW%2FAppKey_Android_SDK.png?alt=media&#x26;token=3095d05c-203c-4317-af96-4b457111c6c9" alt=""><figcaption></figcaption></figure>

### 2. Initialize AppConsent & use it

The second step is to initialize the SDK and wait for it to be started before using it.

{% hint style="success" %}
**TIP**

We recommend you do this in the **Application** class, S**plashscreen**, or your "**android.intent.category.LAUNCHER**" activity.
{% endhint %}

#### **Why timing your consent prompt matters**

First impressions are critical. Users who encounter a consent dialog before experiencing any value from your app are significantly more likely to dismiss it — or abandon the app entirely.

By initializing the SDK early in the background while strategically delaying the CMP display, you ensure that when the consent prompt appears, users are already engaged. This small timing shift can have a measurable impact on positive consent rates, ad revenue, and long-term retention.

The goal is simple : make consent feel like a natural step in the experience, not a barrier to it.

#### **Technical implementation**

The SDK must be initialized as early as possible in your app's lifecycle. On startup, it bootstraps a WebView and initializes its JavaScript engine — a process that takes time. The earlier you trigger this, the sooner the SDK will be ready.

Initialization does not mean the SDK is immediately usable. You must wait for the `onCmpReady` callback before interacting with it. Only at that point can you safely call `getInstance()` and display the CMP.

{% hint style="info" %}
**INFO**

Even if your ad provider registers with the user consent update events and this is transparent to you, some providers may not work correctly with this solution. For this reason, we recommend that you initialize your provider's SDK only when consent has been given, to ensure that your ads are in accordance with user consent. Think to update it each time the user updates his consent too, thank to callbacks
{% endhint %}

{% hint style="info" %}
**INFO**

In the example below, the code focuses on using the SDK **exclusively**.\
The potential **imports** and **visual elements** in these examples are therefore not present, as they are strongly linked to the Android structure and project, which are independent of the SDK.
{% endhint %}

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

```kotlin
class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        SFBX.initialize(
            context = this@MyApplication,
            configuration = Configuration(appkey = "YOUR-APP-KEY"),
            onCmpReady = {
                // SDK is ready — getInstance() can now be called safely
            },
            onCmpOnError = { appconsentExceptions ->
                // An internal error occurred during SDK initialization.
            },
        )
    }
}

class MyActivity : Activity() {
    override fun onCreate() {
        super.onCreate()
        try {
            SFBX.getInstance().presentNotice(
                context = this@MyActivity,
                onCmpDisplayed = {
                    // The CMP is currently being displayed to the user.
                },
                onCmpNotDisplayed = {
                    // The CMP did not display for some reason.
                },
                onCmpClosed = {
                    // The CMP screen has been closed.
                },
            )
        } catch (appconsentExceptions: AppconsentExceptions) {
            // Something goes wrong and the SDK returns a known exception
        } catch (_: Throwable) {
            // Something goes wrong...
        }
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        try {
            SFBX.initialize(
                this,
                new Configuration("YOUR-APP-KEY"),
                appconsent -> {
                    // SDK is ready — getInstance() can now be called safely
                    return Unit.INSTANCE;
                },
                appconsentExceptions -> {
                    // An internal error occurred during SDK initialization.
                    return Unit.INSTANCE;
                }
            );
        } catch (AppconsentExceptions e) {
            // Something goes wrong and the SDK returns a known exception
        } catch (Throwable e) {
            // Something goes wrong...
        }
    }
}

public class MyActivity extends Activity {

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

        try {
            SFBX.getInstance().presentNotice(
                this,
                () -> {
                    // The CMP is currently being displayed to the user.
                    return Unit.INSTANCE;
                },
                () -> {
                    // The CMP did not display for some reason.
                    return Unit.INSTANCE;
                },
                () -> {
                    // The CMP screen has been closed.
                    return Unit.INSTANCE;
                }
            );
        } catch (AppconsentExceptions e) {
            // Something goes wrong and the SDK returns a known exception
        } catch (Throwable e) {
            // Something goes wrong...
        }
    }
}
```

{% endtab %}
{% endtabs %}

#### **Best Practices**

Waiting for the right moment to display the CMP is just as important as initializing the SDK early. Here are a few recommended triggers :

* **Before the first ad load** — ensures consent is collected before any ad request is made, keeping you compliant by design.
* **After the onboarding flow** — the user has already experienced value, making them more likely to engage positively with the consent prompt.
* **At a natural pause in the user journey** — such as between two screens or after a key action, where an interruption feels least disruptive.

{% hint style="danger" %}
Avoid displaying the CMP on the very first screen of your app. Users who haven't yet experienced any value are significantly more likely to dismiss or ignore the prompt.
{% endhint %}

### 3. Suggest CMP to your users

It is also advisable to provide your users with an entry allowing them to view and modify their consent, such as a configuration screen.

{% hint style="info" %}
**INFO**

In the example below, the code focuses on using the SDK **exclusively**.\
The potential **imports** and **visual elements** in these examples are therefore not present, as they are strongly linked to the Android structure and project, which are independent of the SDK.
{% endhint %}

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

```kotlin
class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        findViewById<View>(R.id.button_display_privacy_policy).setOnClickListener {
            try {
                SFBX.getInstance()
            } catch (e: Exception) {
                null
            }?.displayLayer2(
                this@SecondActivity,
                onCmpDisplayed = {
                    // The CMP is currently being displayed to the user.
                },
                onCmpNotDisplayed = {
                    // The CMP did not display for some reason.
                },
                onCmpClosed = {
                    // The CMP screen has been closed.
                },
            )
        }
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
public class SecondActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        findViewById(R.id.button_display_privacy_policy).setOnClickListener(v -> {
            try {
                SFBX.getInstance().displayLayer2(
                    this,
                    () -> {
                        // The CMP is currently being displayed to the user.
                        return Unit.INSTANCE;
                    },
                    () -> {
                        // The CMP did not display for some reason.
                        return Unit.INSTANCE;
                    },
                    () -> {
                        // The CMP screen has been closed.
                        return Unit.INSTANCE;
                    }
                );
            } catch (AppconsentExceptions e) {
                // Something goes wrong and the SDK returns a known exception
            } catch (Throwable e) {
                // Something goes wrong...
            }
        });
    }
}
```

{% endtab %}
{% endtabs %}
