Comment intégrer le SDK CMP UniConsent pour Android avec les applications mobiles

UniConsent CMP est un package pour la gestion du consentement RGPD IAB TCF 2.3 dans les applications Android. Vous pouvez trouver une application de démonstration intégrée avec UniConsent CMP dans le répertoire "demo".

Prérequis

  • Abonnement UniConsent CMP avec prise en charge des applications mobiles
  • Niveau API Android 21 ou supérieur
  • Package SDK UniConsent CMP (à demander auprès du support)

Pour commencer

Ajoutez UniConsentSDK-release.aar dans le répertoire libs/ de votre projet et mettez à jour votre build.gradle :

implementation files('libs/UniConsentSDK-release.aar')
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation 'com.google.android.material:material:1.13.0'
implementation 'com.iabtcf:iabtcf-core:2.0.10'
implementation 'com.iabtcf:iabtcf-decoder:2.0.10'

Personnaliser l'interface de consentement

Avant d'intégrer le SDK, personnalisez l'apparence de la bannière de consentement dans le tableau de bord UniConsent pour correspondre à votre marque et optimiser les taux de consentement.

Étape 1 : Style de marque dans le tableau de bord

Accédez à Projects → Sélectionnez votre projet → Settings → Step 5: UI & Style Settings pour configurer :

  • Main Button Colour — Définissez la couleur du bouton d'action principal pour correspondre à votre marque
  • Main Button Text Colour — Ajustez la couleur du texte sur le bouton principal pour la lisibilité
  • Background Colour — Définissez la couleur de fond de la bannière pour s'harmoniser avec votre application
  • Text Colour — Assurez un contraste approprié pour le texte du corps

Étape 2 : Style avancé avec CSS personnalisé (optionnel)

Pour un contrôle plus précis, ajoutez du CSS personnalisé dans le champ CSS Content sous l'étape 5. Cela est recommandé pour donner à la bannière un aspect natif dans votre application et obtenir le meilleur taux de consentement :

/* Example: Style the accept button to match your brand */
.unic-btn-accept {
  background-color: #4CAF50;
  border-radius: 8px;
  font-weight: 600;
}

/* Example: Adjust banner font */
.unic-banner {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* Example: Make the reject button less prominent */
.unic-btn-reject {
  background-color: transparent;
  border: 1px solid #ccc;
  color: #666;
}

Conseil : Une interface de consentement bien adaptée à votre marque et à l'aspect natif de votre application obtient généralement des taux de consentement plus élevés. Les utilisateurs sont plus enclins à réagir positivement à une bannière qui correspond à l'apparence et au ressenti qu'ils attendent.

Utilisation

Pour utiliser la CMP UniConsent dans votre application, suivez ces étapes :

Initialisez la CMP avec un App ID fourni par votre gestionnaire de compte :

UniConsent UniConsentCMP = UniConsent.getInstance();
UniConsentCMP.setAppId("YOUR_APP_ID");

Affichez l'interface de la CMP :

// Display CMP as full-screen page (default)
UniConsent.getInstance().launchCMP();

// Display CMP as a modal bottom sheet
UniConsent.getInstance().launchCMP(CMPDisplayMode.BOTTOM_SHEET);

// Display CMP as a center dialog
UniConsent.getInstance().launchCMP(CMPDisplayMode.DIALOG);

Vous pouvez également lancer avec une étape et un mode d'affichage spécifiques :

// Launch at a specific stage with a display mode
UniConsent.getInstance().launchCMP(Stage.GDPRFirstScreen, CMPDisplayMode.BOTTOM_SHEET);

// Or set a default display mode for all launches
UniConsent.getInstance().setDisplayMode(CMPDisplayMode.BOTTOM_SHEET);
UniConsent.getInstance().launchCMP();

Vérifier automatiquement si le consentement a expiré lorsque la vendorList est mise à jour :

// Check if consent should be requested (e.g. first visit, or vendor list updated)
if (UniConsentCMP.shouldRequestConsent()) {
    UniConsentCMP.launchCMP();
}

Obtenir le tcString si nécessaire :

// Get tcString
UniConsent.getInstance().getTCString();

Lire le statut du consentement :

// Read consent status
UniConsent.getInstance().hasIABPurposeConsent(1);
UniConsent.getInstance().hasIABVendorConsent(1);

Réinitialiser le statut du consentement si nécessaire :

// Reset consent status
UniConsent.getInstance().clearData();

Synchroniser le consentement avec une WebView

Si votre application ouvre une WebView qui charge une page web avec le tag CMP UniConsent, vous pouvez transmettre le statut de consentement natif afin que le tag CMP reconnaisse le consentement existant et n'affiche pas à nouveau la bannière.

Injectez le consentement au démarrage de la page, avant l'exécution du tag CMP :

WebView webView = findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageStarted(WebView view, String url, android.graphics.Bitmap favicon) {
        UniConsent.getInstance().syncConsent(view);
    }
});

webView.loadUrl("https://example.com");

Exemple avec AppCompatActivity

import com.uniconsent.sdk.CMPDisplayMode;
import com.uniconsent.sdk.Event;
import com.uniconsent.sdk.EventHandler;
import com.uniconsent.sdk.Stage;
import com.uniconsent.sdk.UniConsent;

public class MainActivity extends AppCompatActivity implements EventHandler {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        UniConsent UniConsentCMP = UniConsent.getInstance();
        UniConsentCMP.setAppId("YOUR_APP_ID");
        UniConsentCMP.init(this);
        // register callback events
        UniConsentCMP.subscribe(this);
        // check if consent should be requested
        if (UniConsentCMP.shouldRequestConsent()) {
            UniConsentCMP.launchCMP();
        }
    }

    public void openUniConsentUI(View view) {
        // Full screen
        UniConsent.getInstance().launchCMP(Stage.GDPRFirstScreen);
    }

    public void openAsBottomSheet(View view) {
        // Bottom sheet
        UniConsent.getInstance().launchCMP(Stage.GDPRFirstScreen, CMPDisplayMode.BOTTOM_SHEET);
    }

    public void openAsDialog(View view) {
        // Center dialog
        UniConsent.getInstance().launchCMP(Stage.GDPRFirstScreen, CMPDisplayMode.DIALOG);
    }

    @Override
    public void handle(Event event) {
        UniConsent.getInstance().hasIABVendorConsent(1);
    }
}

Exemple avec ComponentActivity

package com.example.myapplication

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.example.myapplication.ui.theme.MyApplicationTheme
import com.uniconsent.sdk.CMPDisplayMode
import com.uniconsent.sdk.Event
import com.uniconsent.sdk.EventHandler
import com.uniconsent.sdk.Stage
import com.uniconsent.sdk.UniConsent

class MainActivity : ComponentActivity(), EventHandler {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val cmp = UniConsent.getInstance()
        cmp.appId = "YOUR_APP_ID"
        cmp.init(this)
        cmp.subscribe(this)

        if (cmp.shouldRequestConsent()) {
             cmp.launchCMP();
        }
        setContent {
            MyApplicationTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Column(
                        modifier = Modifier
                            .fillMaxSize()
                            .padding(16.dp),
                        verticalArrangement = Arrangement.Center,
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        Button(onClick = {
                            UniConsent.getInstance().launchCMP(Stage.GDPRFirstScreen)
                        }) {
                            Text("Privacy Settings")
                        }
                        Spacer(modifier = Modifier.height(16.dp))
                        Button(onClick = {
                            UniConsent.getInstance().launchCMP(
                                Stage.GDPRFirstScreen, CMPDisplayMode.BOTTOM_SHEET
                            )
                        }) {
                            Text("Privacy Settings (Bottom Sheet)")
                        }
                        Spacer(modifier = Modifier.height(16.dp))
                        Button(onClick = {
                            UniConsent.getInstance().launchCMP(
                                Stage.GDPRFirstScreen, CMPDisplayMode.DIALOG
                            )
                        }) {
                            Text("Privacy Settings (Dialog)")
                        }
                    }
                }
            }
        }
    }

    override fun handle(event: Event?) {
        Log.d("CMP_EVENT", event.toString())
        UniConsent.getInstance().hasIABVendorConsent(1)
    }
}

Permission

<uses-permission android:name="android.permission.INTERNET" />

Configurer le statut de consentement par défaut :

<meta-data android:name="firebase_analytics_collection_enabled" android:value="false" />

<meta-data android:name="google_analytics_default_allow_analytics_storage" android:value="false" />
<meta-data android:name="google_analytics_default_allow_ad_storage" android:value="false" />
<meta-data android:name="google_analytics_default_allow_ad_user_data" android:value="false" />
<meta-data android:name="google_analytics_default_allow_ad_personalization_signals" android:value="false" />

Contrôler les analytics en fonction des indicateurs de consentement :


// <= 25.6.1
override fun handle(event: Event?) {
    Log.d("CMP_EVENT", event.toString())
    if(UniConsent.getInstance().hasIABPurposeConsent(1)) {
        // Set consent types.
        Map<FirebaseAnalytics.ConsentType, FirebaseAnalytics.ConsentStatus> consentMap = new EnumMap<>(FirebaseAnalytics.ConsentType.class);
        consentMap.put(FirebaseAnalytics.ConsentType.ANALYTICS_STORAGE, FirebaseAnalytics.ConsentStatus.GRANTED);
        consentMap.put(FirebaseAnalytics.ConsentType.AD_STORAGE, FirebaseAnalytics.ConsentStatus.GRANTED);
        consentMap.put(FirebaseAnalytics.ConsentType.AD_USER_DATA, FirebaseAnalytics.ConsentStatus.GRANTED);
        consentMap.put(FirebaseAnalytics.ConsentType.AD_PERSONALIZATION, FirebaseAnalytics.ConsentStatus.GRANTED);

        mFirebaseAnalytics.setConsent(consentMap);
        mFirebaseAnalytics.setAnalyticsCollectionEnabled(true);
    } else {
        // Set consent types.
        Map<FirebaseAnalytics.ConsentType, FirebaseAnalytics.ConsentStatus> consentMap = new EnumMap<>(FirebaseAnalytics.ConsentType.class);
        consentMap.put(FirebaseAnalytics.ConsentType.ANALYTICS_STORAGE, FirebaseAnalytics.ConsentStatus.DENIED);
        consentMap.put(FirebaseAnalytics.ConsentType.AD_STORAGE, FirebaseAnalytics.ConsentStatus.DENIED);
        consentMap.put(FirebaseAnalytics.ConsentType.AD_USER_DATA, FirebaseAnalytics.ConsentStatus.DENIED);
        consentMap.put(FirebaseAnalytics.ConsentType.AD_PERSONALIZATION, FirebaseAnalytics.ConsentStatus.DENIED);

        mFirebaseAnalytics.setConsent(consentMap);
        mFirebaseAnalytics.setAnalyticsCollectionEnabled(false);
    }

    // other logics such as send analytics events
}

// > 25.6.1
override fun handle(event: Event?) {
    Log.d("CMP_EVENT", event.toString())

    // other logics such as send analytics events

    // Example: send Firebase event or other analytics metrics
    Bundle bundle = new Bundle();
    bundle.putString(FirebaseAnalytics.Param.ITEM_ID, "id");
    bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, "name");
    bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "image");
    mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle);
}

Pour plus d'informations, consultez Configurer le mode de consentement pour les applications

Modes d'affichage

Le SDK prend en charge trois modes d'affichage pour l'interface de consentement, correspondant à l'API du SDK Flutter :

ModeEnumDescription
Plein écranCMPDisplayMode.FULL_SCREENOuvre la CMP dans une nouvelle activité plein écran (par défaut)
Bottom SheetCMPDisplayMode.BOTTOM_SHEETGlisse depuis le bas sous forme de feuille modale (85 % de hauteur)
DialogueCMPDisplayMode.DIALOGS'affiche sous forme de dialogue centré (90 % de largeur, 75 % de hauteur)

Remarque : Les modes bottom sheet et dialogue nécessitent que votre Activity étende AppCompatActivity ou FragmentActivity.

Remarques

  1. Les utilisateurs doivent avoir la possibilité d'accéder à un bouton ou un lien « Paramètres de confidentialité » dans la section des paramètres de votre application afin d'ouvrir l'interface de la CMP.
  2. Vous pouvez utiliser la fonction shouldRequestConsent() pour vérifier si vous devez demander un nouveau consentement en fonction du statut. Affichez l'interface de la CMP si nécessaire lorsqu'un utilisateur ouvre l'application.
  3. À partir de la version 25.6.1 du SDK, vous n'avez plus besoin d'envoyer manuellement les options de consentement pour FirebaseAnalytics ou certains SDK AAP pris en charge — ils sont gérés automatiquement par le SDK. Pour plus d'informations, consultez Qu'est-ce que Google AAP et Google MMP pour les applications mobiles ?.