---
title: Integrazione Android
slug: it-pubtech-cmp/integrazione-android
docTags: 
createdAt: 2024-05-24T09:59:48.042Z
---

Il PubConsent SDK è l'integrazione del nostro PubConsent CMP nelle applicazioni Android.

Il punto di forza della nostra integrazione è che non richiede molti aggiornamenti poiché molte delle modifiche apportate all'interno del configuratore saranno riflesse automaticamente all'interno dell'app.

**Versione SDK minimo: 21**

:::hint{type="success"}
Ogni volta che verranno introdotte modifiche rilevanti, sarete contattati via email all'indirizzo tecnico che avete configurato nel nostro dashboard per consentirvi di aggiornare la versione del SDK all'ultima che abbiamo pubblicato.
:::

:::hint{type="info"}
Per ulteriori API o maggiori informazioni su come funziona, non esitate a contattare il nostro supporto clienti. Se riscontrate bug o problemi durante l'integrazione per favore non esitate a contattarci, ogni vostro feedback è prezioso per noi.
:::

### Installazione

Il nostro SDK CMP è disponibile su **Maven Central** [cliccando qui.](https://central.sonatype.com/artifact/ai.pubtech/pubconsent)

Per utilizzare il PubConsent SDK nel tuo progetto Android, aggiungi la seguente dipendenza al tuo file `build.gradle`:

```groovy
implementation 'ai.pubtech.pubconsent:pubconsent-sdk:3.0.0'
```

**Permessi**

Questo SDK richiede i seguenti permessi, per favore assicurati di aggiungerli al tuo`AndroidManifest.xml`:

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

### Come funziona

Una volta che l'SDK è integrato in un'app, l'SDK chiederà automaticamente e mostrerà l'interfaccia utente se necessario.
Nel caso sia necessario mostrare l'interfaccia utente l'SDK recupererà le informazioni dal nostro server per preparare e fornire la tua CMP.
L'app può chiedere all'SDK se è stato dato il consenso per lo scopo e/o il fornitore specifici attraverso le API esposte.

### Kotlin Example

```kotlin
import ai.pubtech.pubconsent.Cmp
import ai.pubtech.pubconsent.CmpCallbacks
import ai.pubtech.pubconsent.CmpConfig
import ai.pubtech.pubconsent.dto.GoogleConsentModeStatus
import ai.pubtech.pubconsent.dto.GoogleConsentModeType
import ai.pubtech.pubconsent.utility.CmpLogger
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

       // (Se configuri CmpUIConfig.uiType = CmpUIType.FRAGMENT) allora devi assegnare il tuo fragmentContainerId.
       CmpUIConfig.fragmentContainerId = android.R.id.content

       // Configurazione della UI della CMP.
       CmpUIConfig.configureCenterScreen(this)

       val cmp = Cmp.createInstance(this)

		// Creazione ed assegnazione della callbacks. (opzionale)
        val cmpCallbacks = CmpCallbacks(
            { if (consentApiInterface.getCmpType() == CmpType.TCF_V2_GDPR) {
                consentApiInterface as TCFGDPRConsentApi
                CmpLogger.d("La CMP è basata su TCF V2 per il GDPR ed il consenso è pronto")
                CmpLogger.d("Il vendor 1 è abilitato?: ${cmp.isVendorConsentEnabled(1)}")
                CmpLogger.d("Features: ${cmp.isFeatureCookiesEnabled()}")
                CmpLogger.d("User Experience: ${cmp.isUserExperienceCookiesEnabled()}")
                CmpLogger.d("Measurement: ${cmp.isMeasurementCookiesEnabled()}")

                // Da usare solo se il TCF mobile flag non è abilitato nel configuratore.
                    val firebaseConsentMap = consentApiInterface.getGoogleConsentMode()?.entries?.associate { entry ->
                        val firebaseConsentType = when (entry.key) {
                            GoogleConsentModeType.ANALYTICS_STORAGE -> "FirebaseAnalytics.ConsentType.ANALYTICS_STORAGE"
                            GoogleConsentModeType.AD_STORAGE -> "FirebaseAnalytics.ConsentType.AD_STORAGE"
                            GoogleConsentModeType.AD_USER_DATA -> "FirebaseAnalytics.ConsentType.AD_USER_DATA"
                            GoogleConsentModeType.AD_PERSONALIZATION -> "FirebaseAnalytics.ConsentType.AD_PERSONALIZATION"
                            GoogleConsentModeType.FUNCTIONALITY_STORAGE -> "Opzionale"
                            GoogleConsentModeType.PERSONALIZATION_STORAGE -> "Opzionale"
                            GoogleConsentModeType.SECURITY_STORAGE -> "Opzionale"
                        }

                        val firebaseConsentStatus = when (entry.value) {
                            GoogleConsentModeStatus.GRANTED -> "FirebaseAnalytics.ConsentStatus.GRANTED"
                            GoogleConsentModeStatus.DENIED -> "FirebaseAnalytics.ConsentStatus.DENIED"
                            GoogleConsentModeStatus.UNKNOWN -> "Non mappato nel caso in cui non siano disponibili i tipi opzionali."
                        }

                        firebaseConsentType to firebaseConsentStatus
                    }

                    CmpLogger.d("Firebase mapping $firebaseConsentMap")
                }
                if (consentApiInterface.getCmpType() == CmpType.GOOGLE_CONSENT_MODE) {
                    consentApiInterface as GCMConsentApi
                    CmpLogger.d("La CMP è basata sul Google Consent Mode ed è il consenso è pronto!")

                    val firebaseConsentMap = consentApiInterface.getGoogleConsentMode()?.entries?.associate { entry ->
                        val firebaseConsentType = when (entry.key) {
                            GoogleConsentModeType.ANALYTICS_STORAGE -> "FirebaseAnalytics.ConsentType.ANALYTICS_STORAGE"
                            GoogleConsentModeType.AD_STORAGE -> "FirebaseAnalytics.ConsentType.AD_STORAGE"
                            GoogleConsentModeType.AD_USER_DATA -> "FirebaseAnalytics.ConsentType.AD_USER_DATA"
                            GoogleConsentModeType.AD_PERSONALIZATION -> "FirebaseAnalytics.ConsentType.AD_PERSONALIZATION"
                            GoogleConsentModeType.FUNCTIONALITY_STORAGE -> "Opzionale da abilitare nel configuratore"
                            GoogleConsentModeType.PERSONALIZATION_STORAGE -> "Opzionale da abilitare nel configuratore"
                            GoogleConsentModeType.SECURITY_STORAGE -> "Opzionale da abilitare nel configuratore"
                        }

                        val firebaseConsentStatus = when (entry.value) {
                            GoogleConsentModeStatus.GRANTED -> "FirebaseAnalytics.ConsentStatus.GRANTED"
                            GoogleConsentModeStatus.DENIED -> "FirebaseAnalytics.ConsentStatus.DENIED"
                            GoogleConsentModeStatus.UNKNOWN -> "Non mappato nel caso in cui non siano disponibili i tipi opzionali."
                        }

                        firebaseConsentType to firebaseConsentStatus
                    }

                    CmpLogger.d("Firebase mapping $firebaseConsentMap")
                }
            },
            {
                CmpLogger.d("La CMP UI è stata chiusa (chiamata poco prima del consenso pronto)")
            },
            {
                CmpLogger.d("La CMP UI è stata mostrata")
            },
            {
                CmpLogger.d("Un errore è stato lanciato dalla CMP: $it")
            },
            // Esempio di utilizzo del GoogleConsentMode mapping.
            // ATTENZIONE: Questa callback è deprecata, verrà rimossa nella versione v3.0.0
            { consentMap ->
                val firebaseConsentMap = consentMap.entries.associate { entry ->
                    val firebaseConsentType = when (entry.key) {
                        GoogleConsentModeType.ANALYTICS_STORAGE -> "FirebaseAnalytics.ConsentType.ANALYTICS_STORAGE"
                        GoogleConsentModeType.AD_STORAGE -> "FirebaseAnalytics.ConsentType.AD_STORAGE"
                        GoogleConsentModeType.AD_USER_DATA -> "FirebaseAnalytics.ConsentType.AD_USER_DATA"
                        GoogleConsentModeType.AD_PERSONALIZATION -> "FirebaseAnalytics.ConsentType.AD_PERSONALIZATION"
                    }

                    val firebaseConsentStatus = when (entry.value) {
                        GoogleConsentModeStatus.GRANTED -> "FirebaseAnalytics.ConsentStatus.GRANTED"
                        GoogleConsentModeStatus.DENIED -> "FirebaseAnalytics.ConsentStatus.DENIED"
                    }

                    firebaseConsentType to firebaseConsentStatus
                }

                CmpLogger.d("Firebase mapping $firebaseConsentMap")
            }
        )

		// Creazione della configurazione per avviare la CMP.
        val cmpConfig = CmpConfig("your_cmp_id", appName = "your_app_name", true, cmpCallbacks)

		// Avvio della CMP.
        cmp.run(this, cmpConfig)

        val button = findViewById<Button>(R.id.button)

        // Utilizzo del metodo showNotice (il precedente askConsent nella 2.0.0) per associarlo ad un bottone di riapertura della CMP.
        button.setOnClickListener {
            cmp.showNotice(this)
        }
    }
}

```

### Java Example

```java
import ai.pubtech.pubconsent.Cmp;
import ai.pubtech.pubconsent.CmpCallbacks;
import ai.pubtech.pubconsent.CmpConfig;
import ai.pubtech.pubconsent.dto.GoogleConsentModeStatus;
import ai.pubtech.pubconsent.dto.GoogleConsentModeType;
import ai.pubtech.pubconsent.utility.CmpLogger;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

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

        // (Se configuri CmpUIConfig.uiType = CmpUIType.FRAGMENT) allora devi assegnare il tuo fragmentContainerId.
        CmpUIConfig.fragmentContainerId = android.R.id.content;

        // Configurazione della UI della CMP.
        CmpUIConfig.INSTANCE.configureCenterScreen(this);

        // Creazione dell'istanza CMP.
        Cmp cmp = Cmp.INSTANCE.createInstance(this);

        // Creazione ed assegnazione della callbacks. (opzionale)
        CmpCallbacks cmpCallbacks = new CmpCallbacks(
            consentApiInterface -> {
                if (consentApiInterface.getCmpType() == CmpType.TCF_V2_GDPR) {
                    TCFGDPRConsentApi gdprConsentApi = (TCFGDPRConsentApi) consentApiInterface;
                    CmpLogger.d("La CMP è basata su TCF V2 per il GDPR ed il consenso è pronto");
                    CmpLogger.d("Il vendor 1 è abilitato?: " + cmp.isVendorConsentEnabled(1));
                    CmpLogger.d("Features: " + cmp.isFeatureCookiesEnabled());
                    CmpLogger.d("User Experience: " + cmp.isUserExperienceCookiesEnabled());
                    CmpLogger.d("Measurement: " + cmp.isMeasurementCookiesEnabled());

                    Map<String, String> firebaseConsentMap = gdprConsentApi.getGoogleConsentMode().entrySet().stream().collect(Collectors.toMap(
                        entry -> {
                            switch (entry.getKey()) {
                                case ANALYTICS_STORAGE:
                                    return "FirebaseAnalytics.ConsentType.ANALYTICS_STORAGE";
                                case AD_STORAGE:
                                    return "FirebaseAnalytics.ConsentType.AD_STORAGE";
                                case AD_USER_DATA:
                                    return "FirebaseAnalytics.ConsentType.AD_USER_DATA";
                                case AD_PERSONALIZATION:
                                    return "FirebaseAnalytics.ConsentType.AD_PERSONALIZATION";
                                case FUNCTIONALITY_STORAGE:
                                    return "Opzionale";
                                case PERSONALIZATION_STORAGE:
                                    return "Opzionale";
                                case SECURITY_STORAGE:
                                    return "Opzionale";
                                default:
                                    return "";
                            }
                        },
                        entry -> {
                            switch (entry.getValue()) {
                                case GRANTED:
                                    return "FirebaseAnalytics.ConsentStatus.GRANTED";
                                case DENIED:
                                    return "FirebaseAnalytics.ConsentStatus.DENIED";
                                case UNKNOWN:
                                    return "Non mappato nel caso in cui non siano disponibili i tipi opzionali.";
                                default:
                                    return "";
                            }
                        }
                    ));

                    CmpLogger.d("Firebase mapping " + firebaseConsentMap);

                } else if (consentApiInterface.getCmpType() == CmpType.GOOGLE_CONSENT_MODE) {
                    GCMConsentApi gcmConsentApi = (GCMConsentApi) consentApiInterface;
                    CmpLogger.d("La CMP è basata sul Google Consent Mode ed è il consenso è pronto!");

                    Map<String, String> firebaseConsentMap = gcmConsentApi.getGoogleConsentMode().entrySet().stream().collect(Collectors.toMap(
                        entry -> {
                            switch (entry.getKey()) {
                                case ANALYTICS_STORAGE:
                                    return "FirebaseAnalytics.ConsentType.ANALYTICS_STORAGE";
                                case AD_STORAGE:
                                    return "FirebaseAnalytics.ConsentType.AD_STORAGE";
                                case AD_USER_DATA:
                                    return "FirebaseAnalytics.ConsentType.AD_USER_DATA";
                                case AD_PERSONALIZATION:
                                    return "FirebaseAnalytics.ConsentType.AD_PERSONALIZATION";
                                case FUNCTIONALITY_STORAGE:
                                    return "Opzionale da abilitare nel configuratore";
                                case PERSONALIZATION_STORAGE:
                                    return "Opzionale da abilitare nel configuratore";
                                case SECURITY_STORAGE:
                                    return "Opzionale da abilitare nel configuratore";
                                default:
                                    return "";
                            }
                        },
                        entry -> {
                            switch (entry.getValue()) {
                                case GRANTED:
                                    return "FirebaseAnalytics.ConsentStatus.GRANTED";
                                case DENIED:
                                    return "FirebaseAnalytics.ConsentStatus.DENIED";
                                case UNKNOWN:
                                    return "Non mappato nel caso in cui non siano disponibili i tipi opzionali.";
                                default:
                                    return "";
                            }
                        }
                    ));

                    CmpLogger.INSTANCE.d("Firebase mapping " + firebaseConsentMap);
                }
            },
            () -> {
                CmpLogger.INSTANCE.d("La CMP UI è stata chiusa (chiamata poco prima del consenso pronto)");
            },
            () -> {
                CmpLogger.INSTANCE.d("La CMP UI è stata mostrata");
            },
            error -> {
                CmpLogger.INSTANCE.d("Un errore è stato lanciato dalla CMP: " + error);
            },
            consentMap -> {
                Map<String, String> firebaseConsentMap = consentMap.entrySet().stream().collect(Collectors.toMap(
                    entry -> {
                        switch (entry.getKey()) {
                            case ANALYTICS_STORAGE:
                                return "FirebaseAnalytics.ConsentType.ANALYTICS_STORAGE";
                            case AD_STORAGE:
                                return "FirebaseAnalytics.ConsentType.AD_STORAGE";
                            case AD_USER_DATA:
                                return "FirebaseAnalytics.ConsentType.AD_USER_DATA";
                            case AD_PERSONALIZATION:
                                return "FirebaseAnalytics.ConsentType.AD_PERSONALIZATION";
                            default:
                                return "";
                        }
                    },
                    entry -> {
                        switch (entry.getValue()) {
                            case GRANTED:
                                return "FirebaseAnalytics.ConsentStatus.GRANTED";
                            case DENIED:
                                return "FirebaseAnalytics.ConsentStatus.DENIED";
                            default:
                                return "";
                        }
                    }
                ));

                CmpLogger.INSTANCE.d("Firebase mapping " + firebaseConsentMap);
            }
        );

        // Creazione della configurazione per avviare la CMP.
        CmpConfig cmpConfig = new CmpConfig("your_cmp_id", "your_app_name", true, cmpCallbacks);

        // Avvio della CMP.
        cmp.run(this, cmpConfig);

        // Pulsante di apertura CMP.
        Button button = findViewById(R.id.button);
        button.setOnClickListener(v -> cmp.showNotice(this));
    }
}

```

## Condivisione consenso con una WebView

Se hai bisogno di riutilizzare il consenso collezionato attraverso la nostra SDK ad una WebView che punta al tuo sito web puoi consultare la documentazione [Condivisione consensi alle WebView](docId\:QOBtYq9cDN12Ny4SQG_EG) .

## Configurazione del layout

Per configurare il layout puoi usare la classe `CmpUIConfig` con diverse opzioni di stile. Questa classe offre anche alcuni layout preimpostati come

- configureHalfScreenBottom
- configureHalfScreenTop
- configureCenterScreen
- configureSmallCenterScreen
- configureLargeTopScreen
- configureLargeBottomScreen

Il tipo di interfaccia utente predefinito sarà quello che utilizza la finestra popup. Puoi cambiare il tipo di interfaccia utente impostando il parametro UIConfig:

- CmpUIConfig.uiType = CmpUIType.DIALOG
- CmpUIConfig.uiType = CmpUIType.POPUP
- CmpUIConfig.uiType = CmpUIType.FRAGMENT
- CmpUIConfig.uiType = CmpUIType.ACTIVITY

Due importanti parametri determineranno il comportamento del popup e del dialogo:

### Comportamento del Popup

| Parametro                  | isFocusable = true                                                                             | isFocusable = false                                                                                  |
| -------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| isOutsideTouchable =  true | Rimuove toccando all'esterno. Può acquisire il focus per eventi di input.                      | Rimuove toccando all'esterno. Non acquisisce il focus o intercetta l'input della tastiera.           |
| isOutsideTouchable = false | Non viene rimosso toccando all'esterno. Può acquisire il focus e intercettare eventi di input. | Non viene rimosso toccando all'esterno. Non acquisisce il focus o intercetta l'input della tastiera. |

### Comportamento del Dialog

| Parametro                  | isFocusable = true                                                                                                                            | isFocusable = false                                                                                                                      |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| isOutsideTouchable =  true | Rimuove con un tocco all'esterno (`setCanceledOnTouchOutside(true)`). Il dialogo è di default focusabile.                                     | Il dialogo non viene chiuso toccando all'esterno e potrebbe non comportarsi come previsto poiché i dialoghi sono tipicamente focusabili. |
| isOutsideTouchable = false | Non viene rimosso toccando all'esterno (`setCanceledOnTouchOutside(false)`). Il dialogo rimane focusabile e può intercettare eventi di input. | Il dialogo non viene chiuso toccando all'esterno e potrebbe non comportarsi come previsto a causa della mancanza di focusabilità.        |

### Esempio per il FragmentLayout:

`R.id.cmpContainer` è un `Framelayout` che potrebbe apparire così nel file xml del layout dell'attività in `layout/{tua_attività}.xml`.

### Prevenire l'azione back quando la UI è mostrata

Per evitare la chiusura dell'interfaccia utente (UI), è necessario eseguire l'override della funzione `onBackPressed` e verificare che la CMP non sia mostrata. Per controllare se la UI della CMP è visualizzata, potete affidarvi alle callback precedentemente illustrate.

```kotlin
Inside your activity class...

override fun onBackPressed() {
   if (isCmpOpen) {
      return
   }
   super.onBackPressed()
}
```

## Integrazione Google Consent Mode (v2)

Google Consent Mode ti permette di regolare il comportamento dei tag Google e del Firebase SDK in base allo stato del consenso dell'utente. Per conformarsi alla policy aggiornata di Google (EU user consent policy), il PubTech CMP supporta i quattro parametri obbligatori: ad\_storage, analytics\_storage, ad\_user\_data, e ad\_personalization.

**1. Imposta gli stati di consenso predefiniti (Default States)** Prima che il CMP venga inizializzato, dovresti definire gli stati di consenso predefiniti nei file di configurazione della tua app.

**Android (AndroidManifest.xml):**&#x41;ggiungi i seguenti tag \<meta-data> all'interno del tag \<application>:

```xml
<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" />
```

**2. Sincronizzazione del consenso con Firebase SDK&#x20;**&#x44;evi aggiornare il Firebase SDK ogni volta che la CMP cattura o aggiorna il consenso dell'utente. Usa la callback onConsentReady per mappare i tipi di consenso di PubTech su Firebase.

```kotlin
import com.google.firebase.analytics.FirebaseAnalytics

val cmpCallbacks = CmpCallbacks(
    onConsentReadyCallback = { consentApi ->
        val gcm = consentApi.getGoogleConsentMode()
        val consentMap = mutableMapOf<FirebaseAnalytics.ConsentType, FirebaseAnalytics.ConsentStatus>()

        gcm?.forEach { (type, status) ->
            val firebaseType = when(type) {
                GoogleConsentModeType.ANALYTICS_STORAGE -> FirebaseAnalytics.ConsentType.ANALYTICS_STORAGE
                GoogleConsentModeType.AD_STORAGE -> FirebaseAnalytics.ConsentType.AD_STORAGE
                GoogleConsentModeType.AD_USER_DATA -> FirebaseAnalytics.ConsentType.AD_USER_DATA
                GoogleConsentModeType.AD_PERSONALIZATION -> FirebaseAnalytics.ConsentType.AD_PERSONALIZATION
                else -> null
            }
            val firebaseStatus = if (status == GoogleConsentModeStatus.GRANTED) 
                FirebaseAnalytics.ConsentStatus.GRANTED else FirebaseAnalytics.ConsentStatus.DENIED

            firebaseType?.let { consentMap[it] = firebaseStatus }
        }
        FirebaseAnalytics.getInstance(context).setConsent(consentMap)
    }
)
```

**3. Verifica** Per verificare che i segnali vengano inviati correttamente:

Esegui `adb shell setprop log.tag.FA-SVC VERBOSE` e controlla Logcat cercando la stringa "Setting consent".

## SDK & APIs Documentation

### `Cmp` class

Constructors

1. &#x20;`Cmp(Context context)`
   - **Descrizione**: Inizializza il CMP con il contesto specificato e l'ID della vista del contenuto.
   - **Parametri**:
     - `context`: Il context della tua application/activity.

Public Methods

1. &#x20;`run(Context context, CmpConfig cmpConfig)`
   - **Descrizione**: Avvia il CMP con la configurazione fornita.
   - **Parametri**:
     - `context`: Il context della tua application/activity.
     - `cmpConfig`: L'oggetto di configurazione per il CMP.
   - **Uso**: Questo metodo inizializza e avvia il CMP con la configurazione specificata.
2. &#x20;`showNotice(Activity activity)`
   - **Descrizione**: Visualizza la finestra del CMP per chiedere il consenso dell'utente.
   - **Parametri**:
     - `activity`: Il contesto dell'attività dove verrà visualizzata la finestra del CMP.
   - **Uso**: Chiama questo metodo per richiedere il consenso dell'utente utilizzando la finestra del CMP (per implementare il bottone di riapertura).

### `CmpConfig` Class

Constructors

1. &#x20;`CmpConfig(id: String, appName: String, callbacks: CmpCallbacks, debug: Boolean, retryConfig: RetryConfig)`
   - **Descrizione**: Constructs a configuration object for the CMP.
   - **Parametri**:
     - `id`: L'ID del CMP.
     - `appName`: Il nome dell'applicazione.
     - `callbacks`: Funzioni di callback per gli eventi del CMP.
     - `debug`: Per scopi di debug.
     - `retryConfig`: Per configurare i parametri disponibili dal meccanismo di riprova.

### `RetryConfig` Class

Constructors

1. &#x20;`RetryConfig(maxRetries: Int, retryDelay: Int, retriesBackOffFactor: Double, timeout: Long)`
   - **Descrizione**: Oggetto per il meccanismo di retry di apertura della CMP nel caso di problemi con la rete.
   - **Parametri**:
     - `maxRetries`: Il numero massimo di tentativi di riprova. Il valore predefinito è 3.
     - `retryDelay`: Il ritardo (in millisecondi) tra i tentativi di riprova consecutivi. Il valore predefinito è 200.
     - `retriesBackOffFactor`: Il fattore con cui il ritardo di riprova dovrebbe essere moltiplicato per il ritardo esponenziale. Il valore predefinito è 1.3.
     - `timeout`: La durata massima (in millisecondi) entro la quale i tentativi di riprova devono essere completati. Il valore predefinito è 7500.

### `CmpCallbacks` Interface

Methods

1. &#x20;`onConsentReadyCallback(consentApiInterface: ConsentApiInterface)`
   - **Descrizione**: Callback function chiamata quando il consenso è presente.
   - **Nota**: In seguito trovate la documentazione sulle implementazioni disponibili dell'interfaccia `ConsentApiInterface`
2. &#x20;`onCmpUIClosedCallback()`
   - **Descrizione**: Callback function chiamata quando la UI della CMP viene chiusa.
3. &#x20;`onCmpUIOpenCallback()`
   - **Descrizione**: Callback function chiamata quando la UI della CMP viene mostrata all'utente.
4. &#x20;`onErrorCallback(error: String)`
   - **Descrizione**: Callback function chiamata quando accade un errore.
   - **Parametri**:
     - `error`: Descrizione dell'errore.
5. &#x20;`onGoogleConsentModeCallback(consentMap: Map<Int, Int>)`
   - **Descrizione**: Callback function chiamata quando il mapping per il Google Consent Mode è pronto.
   - **Parametri**:
     - `consentMap`: contiente il mapping dei consensi per Google Consent Mode.

## PubConsent `ConsentApiInterface`

Utilizzando l'API esposta tramite `onConsentReadyCallback` potete verificare tramite il metodo `getCmpType()` quali delle seguenti implementazioni avete a disposizione (questa scelta dipende dalla configurazione salvata attraverso il configuratore PubConsent). Di seguito vi mostriamo le API per ogni CMP Type che offriamo seguenti metodi sono accessibili tramite l'istanza `consentApiInstance: any PubConsent.ConsentApiInterface` disponibile come parametro alla callback: `onConsentReadyCallback`

## API per il CmpType.TCF\_V2\_GDPR

Quando il consenso è relativo alla CMP TCF (ovvero `consentApiInterface.getCmpType() == CmpType.TCF_V2_GDPR`)  avrete a disposizione le seguenti API:

- `isVendorConsentEnabled(vendorId: Int): Boolean`
  - **Descrizione**: Verifica se il consenso è abilitato per un fornitore specifico.
  - **Parametri**:
    - `vendorId`: L'ID del fornitore per cui verificare il consenso.
  - **Returns**: `true` se il consenso è abilitato per il fornitore specificato, altrimenti false.
  - **Uso**: Utilizza questo metodo per determinare se il consenso è stato concesso per un particolare fornitore.
- &#x20;`isPurposeConsentEnabled(purposeId: Int): Boolean`
  - **Descrizione**: Verifica se il consenso è abilitato per un fornitore specifico.
  - **Parametri**:
    - `purposeId`: L'ID dello scopo per il quale verificare il consenso.
  - **Returns**: `true`  se il consenso è abilitato per lo scopo specificato, altrimenti false.
  - **Uso**: Utilizza questo metodo per determinare se il consenso è stato concesso per uno scopo particolare.
- &#x20;`isFeatureCookiesEnabled(): Boolean`
  - **Descrizione**: Verifica se il consenso è abilitato per i cookie delle funzionalità.
  - **Returns**:  `true` se il consenso è abilitato per i cookie delle funzionalità, altrimenti false.
  - **Uso**: Utilizza questo metodo per determinare se il consenso è stato concesso per i cookie delle funzionalità.
- &#x20;`isUserExperienceCookiesEnabled(): Boolean`
  - **Descrizione**: Verifica se il consenso è abilitato per i cookie dell'esperienza utente.
  - **Returns**: `true` Se il consenso è abilitato per i cookie dell'esperienza utente, altrimenti false.
  - **Uso**: Utilizza questo metodo per determinare se il consenso è stato concesso per i cookie dell'esperienza utente.
- &#x20;`isMeasurementCookiesEnabled(): Boolean`
  - **Descrizione**: Verifica se il consenso è abilitato per i cookie di misurazione.
  - **Returns**: `true`  se il consenso è abilitato per i cookie di misurazione, altrimenti.
  - **Uso**: Utilizza questo metodo per determinare se il consenso è stato concesso per i cookie di misurazione.
- `getGoogleConsentMode() : Map<GoogleConsentModeType, GoogleConsentModeStatus>?`
  - **Descrizione**: Recupera lo stato del Google Consent Mode per i vari tipi di consenso supportati.
  - **Returns**: Una mappa contenente i tipi di consenso (GoogleConsentModeType) e il relativo stato (GoogleConsentModeStatus).
    Restituisce null se nessuna configurazione è disponibile.
  - **Uso**: Utilizza questo metodo per ottenere lo stato dei consensi associati al Google Consent Mode e determinare se il consenso è stato concesso, negato o è sconosciuto per ciascun tipo di consenso.

## API per il CmpType.GOOGLE\_CONSENT\_MODE

Quando il consenso è relativo alla CMP basata solo su Google Consent Mode (ovvero `consentApiInterface.getCmpType() == CmpType.GOOGLE_CONSENT_MODE`)  avrete a disposizione le seguenti API:

- `getGoogleConsentMode() : Map<GoogleConsentModeType, GoogleConsentModeStatus>?`
  - **Descrizione**: Recupera lo stato del Google Consent Mode per i vari tipi di consenso supportati.
  - **Returns**: Una mappa contenente i tipi di consenso (GoogleConsentModeType) e il relativo stato (GoogleConsentModeStatus).
    Restituisce null se nessuna configurazione è disponibile.
  - **Uso**: Utilizza questo metodo per ottenere lo stato dei consensi associati al Google Consent Mode e determinare se il consenso è stato concesso, negato o è sconosciuto per ciascun tipo di consenso.

## Troubleshooting

### ProGuard bugs

ProGuard può talvolta offuscare i nomi delle classi o rimuovere i metodi che vengono richiamati dinamicamente tramite reflection. Per risolvere questo problema, è necessario specificare le classi e i metodi che devono rimanere intatti nel file di configurazione di ProGuard utilizzando la direttiva -keep.

