Compliant with GDPR, CCPA, COPPA, LGPD, PECR, PDPA, PIPEDA, and more.
UniConsent CMP è un pacchetto per la gestione del consenso GDPR IAB TCF 2.4 nelle app Android. Nella directory "demo" trovi un'app dimostrativa integrata con UniConsent CMP.
Aggiungi UniConsentSDK-release.aar alla directory libs/ del tuo progetto e aggiorna il file 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'
Prima di integrare l'SDK, personalizza l'aspetto del banner del consenso nella Dashboard UniConsent per adattarlo al tuo brand e ottimizzare i tassi di consenso.
Vai a Projects → Select your Project → Settings → Step 5: UI & Style Settings per configurare:
Per un controllo più preciso, aggiungi CSS personalizzato nel campo CSS Content del passaggio 5. È consigliato per far sembrare il banner parte integrante della tua app e ottenere il miglior tasso di consenso:
/* 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;
}
Suggerimento: un'interfaccia del consenso coerente con il brand e integrata nella tua app ottiene in genere tassi di consenso più elevati. Gli utenti tendono a interagire in modo più positivo con un banner che rispecchia l'aspetto e lo stile che si aspettano.
Per usare UniConsent CMP nella tua app, segui questi passaggi:
Inizializza la CMP con un App ID fornito dal tuo account manager:
UniConsent UniConsentCMP = UniConsent.getInstance();
UniConsentCMP.setAppId("YOUR_APP_ID");
Mostra l'interfaccia della 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);
Puoi anche avviarla con una fase e una modalità di visualizzazione specifiche:
// Launch at a specific stage with a display mode
UniConsent.getInstance().launchCMP(Stage.GDPRFirstScreen, CMPDisplayMode.BOTTOM_SHEET);
// Bottom sheet at 70% of the screen height
UniConsent.getInstance().launchCMP(Stage.GDPRFirstScreen, CMPDisplayMode.BOTTOM_SHEET, 0.7);
// Center dialog at 80% width and 60% height
UniConsent.getInstance().launchCMP(Stage.GDPRFirstScreen, CMPDisplayMode.DIALOG, 0.8, 0.6);
// Or set a default display mode for all launches
UniConsent.getInstance().setDisplayMode(CMPDisplayMode.BOTTOM_SHEET);
UniConsent.getInstance().launchCMP();
Disponibile dalla versione 26.8.0 dell'SDK.
Entrambi i rapporti sono facoltativi: ogni modalità di visualizzazione funziona anche senza. Passa un rapporto (una frazione dello schermo, maggiore di 0 e al massimo 1) solo per sovrascrivere le dimensioni predefinite; i valori non validi generano IllegalArgumentException:
| Parametro | Si applica a | Valore predefinito se omesso |
|---|---|---|
heightRatio | BOTTOM_SHEET, DIALOG | Sheet: 90% dello schermo. Dialog: 70% |
widthRatio | Solo DIALOG | 90% della larghezza dello schermo, fino a 500dp |
I rapporti che non si applicano alla modalità di visualizzazione scelta vengono ignorati (FULL_SCREEN li ignora entrambi).
Verifica automaticamente se il consenso è scaduto quando la vendorList viene aggiornata:
// Check if consent should be requested (e.g. first visit, or vendor list updated)
if (UniConsentCMP.shouldRequestConsent()) {
UniConsentCMP.launchCMP();
}
Ottieni la tcString, se necessario:
// Get tcString
UniConsent.getInstance().getTCString();
Leggi lo stato del consenso:
// Read consent status
UniConsent.getInstance().hasIABPurposeConsent(1);
UniConsent.getInstance().hasIABVendorConsent(1);
Reimposta lo stato del consenso, se necessario:
// Reset consent status
UniConsent.getInstance().clearData();
Disponibile dalla versione 26.7.0 dell'SDK. Se crei una tua interfaccia di primo livello per il consenso invece di mostrare la webview della CMP, puoi salvare il consenso direttamente:
// Grant consent for all purposes, special features and vendors
boolean saved = UniConsent.getInstance().agreeAll();
// Reject all purposes, special features and vendors
boolean saved = UniConsent.getInstance().rejectAll();
Entrambe le API salvano gli stessi valori di consenso del flusso dell'interfaccia della CMP (chiavi IAB TCF, additional consent e segnali di Consent Mode) e inviano lo stesso evento di chiusura ai sottoscrittori.
Nota: chiama queste API solo dopo il completamento di
init()(ad esempio dopo l'evento READY). Richiedono la vendor list e la configurazione del progetto, che vengono recuperate durante l'inizializzazione, e restituisconofalsese non è stato possibile salvare il consenso.Importante: il tuo primo livello personalizzato deve comunque rispettare i requisiti IAB TCF (indicare le finalità e i fornitori e offrire le opzioni di accettazione e rifiuto con uguale evidenza). Gli utenti devono comunque poter aprire l'interfaccia completa della CMP (
launchCMP()) per effettuare scelte granulari.
Se la tua app apre una WebView che carica una pagina web con il tag CMP di UniConsent, puoi passare lo stato del consenso nativo in modo che il tag CMP riconosca il consenso esistente e non mostri di nuovo il banner.
Inietta il consenso all'avvio della pagina, prima che venga eseguito il 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");
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);
}
}
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)
}
}
<uses-permission android:name="android.permission.INTERNET" />
Configura i valori chiave (KV) predefiniti dello stato del consenso:
<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" />
Controlla gli analytics in base ai flag del consenso:
// <= 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 logic such as send analytics events
}
// > 25.6.1
override fun handle(event: Event?) {
Log.d("CMP_EVENT", event.toString())
// other logic 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);
}
Trova maggiori informazioni in Set up consent mode for apps
L'SDK supporta tre modalità di visualizzazione per l'interfaccia del consenso, in linea con l'API dell'SDK Flutter:
| Modalità | Enum | Descrizione |
|---|---|---|
| Schermo intero | CMPDisplayMode.FULL_SCREEN | Apre la CMP in una nuova activity a schermo intero (predefinita) |
| Bottom sheet | CMPDisplayMode.BOTTOM_SHEET | Scorre dal basso come foglio modale (85% dell'altezza) |
| Dialog | CMPDisplayMode.DIALOG | Viene mostrata come finestra di dialogo centrata (90% della larghezza, 75% dell'altezza) |
Nota: le modalità bottom sheet e dialog richiedono che la tua Activity estenda
AppCompatActivityoFragmentActivity.