[Android] 1. Integracja SDK Consentmanager

W tym dokumencie znajdziesz ogólne informacje na temat integracji naszego SDK z Twoim projektem. Aby uzyskać więcej szczegółów, zapoznaj się z naszą dokumentacją API Reference. Wszystkie poniższe fragmenty kodu zostały zaczerpnięte z naszej aplikacji demonstracyjnej

1. Instalacja

consentmanager SDK to kompleksowe rozwiązanie do zarządzania zgodą użytkownika w aplikacjach mobilnych. Zaprojektowany z myślą o zgodności z RODO, preferencjach użytkowników dotyczących prywatności oraz przejrzystości śledzenia reklam, ten SDK zapewnia płynną integrację z platformami iOS i Android. Dodatkowo oferuje wtyczki/mostki dla React Native, Flutter i Unity, dzięki czemu jest wszechstronny w różnych środowiskach programistycznych.

Kroki – ogólny opis

  1. Integracja i konfiguracja:

    • Zintegruj SDK z aplikacją.
    • Skonfiguruj ustawienia SDK zgodnie ze swoimi potrzebami.
  2. Tworzenie instancji i wyświetlanie warstwy zgody:

    • Po uruchomieniu aplikacji utwórz instancję klasy CMPManager klasy. Instancja ta będzie obsługiwać proces uzyskiwania zgody.
    • W razie potrzeby SDK automatycznie wyświetli ekran zgody.
  3. Przetwarzanie danych dotyczących zgody użytkownika:

    • Po zebraniu zgód informacje są przechowywane i dostępne do wyszukiwania za pomocą różnych właściwości i metod udostępnianych przez nasz SDK. Będziesz mieć informacje o odrzuconych lub zaakceptowanych zgodach, dostawcach i celach.

1.1 Integracja i konfiguracja

Dodawanie zależności za pomocą Gradle

Dodaj następujący wiersz do pliku build.gradle:

dependencies {
    implementation "net.consentmanager.sdkv3:cmsdkv3:3.2.0"
}

Następnie zsynchronizuj swój projekt. 

1.2 Tworzenie instancji i wyświetlanie warstwy zgody

W ramach funkcji app-start (twojej onCreate funkcji) musisz utworzyć instancję klasy CMPManager. Musisz skonfigurować dwa obiekty, które zostaną przekazane do metody getInstance: UrlConfig, która obsługuje konfigurację CMP, taką jak identyfikator kodu i domyślny język, oraz ConsentLayerUIConfig, która skonfiguruje wygląd WebView, w którym wyświetlona zostanie warstwa zgody. Następnie przekażesz bieżącą Activity za pomocą metody setActivityi przypisz delegata, jak pokazano poniżej. W poniższym przykładzie możesz znaleźć oba przekazywane obiekty. Funkcja checkAndOpen() Funkcja automatycznie pobierze niezbędne dane z naszego serwera i ustali, czy ekran zgody musi zostać wyświetlony, czy nie. Jeśli tak, SDK automatycznie wyświetli w tym momencie ekran zgody za pośrednictwem WebView utworzonego przez nasz SDK, który wyświetli warstwę zgody z tekstem i przyciskami zgodnie z konfiguracjami CMP (wybranymi za pomocą identyfikatora Code-ID CMP), zbierze dane i zapisze informacje o zgodzie w obszarze NSUserDefaults urządzenia, dzięki czemu aplikacja będzie mogła odpowiednio wyświetlać reklamy ukierunkowane. 

Pamiętaj, że kluczowe znaczenie ma zadeklarowanie i zainicjowanie CMPManager SDK w onCreate , w przeciwnym razie widok może nie być gotowy do użycia, a SDK może nie działać. Proszę również przestrzegać wzorca singleton, aby mieć tylko jedną instancję SDK. Upewnij się również, że używasz prawidłowych danych konfiguracyjnych. Dane konfiguracyjne można znaleźć na koncie ConsentManager w Menu > CMP > Pobierz kod dla aplikacji > ID kodu

Należy również pamiętać, że funkcje związane z ustalaniem, czy zgoda jest potrzebna, czy nie, a także wyświetlanie warstwy zgody, zależą od niezawodnego połączenia sieciowego. Jeśli nie ma dostępnego połączenia lub jeśli mechanizm ponownej próby nie zdoła połączyć się z naszym serwerem, zdarzenie didReceiveError zwróci błąd przekroczenia limitu czasu, a zatem SDK nie będzie w stanie w ogóle ustalić konieczności uzyskania zgody, ponieważ nie będzie w stanie wyświetlić warstwy zgody. Proszę upewnić się, że logika uwzględnia ten fakt.

Przykład:

import net.consentmanager.cm_sdk_android_v3.CMPManager
import net.consentmanager.cm_sdk_android_v3.CMPManagerDelegate
import net.consentmanager.cm_sdk_android_v3.ConsentLayerUIConfig
import net.consentmanager.cm_sdk_android_v3.UrlConfig

class MainActivity : ComponentActivity(), CMPManagerDelegate {
    private lateinit var cmpManager: CMPManager

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

        val urlConfig = UrlConfig(
            id = "YOUR_CODE_ID_HERE",
            domain = "delivery.consentmanager.net",
            language = "EN",
            appName = "CMDemoAppKotlin"
        )

        val webViewConfig = ConsentLayerUIConfig(
            position = ConsentLayerUIConfig.Position.FULL_SCREEN,
            backgroundStyle = ConsentLayerUIConfig.BackgroundStyle.dimmed(Color.BLACK, 0.5f),
            cornerRadius = 10f,
            respectsSafeArea = true,
            isCancelable = false
        )

        cmpManager = CMPManager.getInstance(
            context = this,
            urlConfig = urlConfig,
            webViewConfig = webViewConfig,
            delegate = this
        )

        cmpManager.setActivity(this)

        checkAndOpen()
    }

    private fun checkAndOpenConsentLayer() {
        cmpManager.checkAndOpen { result ->
            result.onSuccess {
                showCMPDemoScreen()
            }.onFailure { error ->
                Log.e("DemoApp", "Check and open consent layer failed with error: $error")
            }
        }
    }

    private fun showCMPDemoScreen() {
        setContent {
            MaterialTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    CMPDemoScreen(cmpManager)
                }
            }
        }
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        Log.d("CMP DemoApp", "Configuration changed")
        super.onConfigurationChanged(newConfig)
        cmpManager.onApplicationResume()
    }

	override fun onPause() {
        Log.d("CMP DemoApp", "Activity paused")
        super.onPause()
        cmpManager.onApplicationPause()
    }

    override fun onDestroy() {
        Log.d("CMP DemoApp", "Activity destroyed")
        super.onDestroy()
        cmpManager.onActivityDestroyed()
    }

    override fun didReceiveConsent(consent: String, jsonObject: Map<String, Any>) {
        Log.d("CMP DemoApp", "Consent Layer successfully received consent message.")
        runOnUiThread {
            showCMPDemoScreen()
        }
    }

    override fun didShowConsentLayer() {
        Log.d("CMP DemoApp", "Consent Layer open message received.")
    }

    override fun didCloseConsentLayer() {
        Log.d("CMP DemoApp", "Consent Layer close message received.")
        runOnUiThread {
            showCMPDemoScreen()
        }
    }

    override fun didReceiveError(error: String) {
        Log.e("CMP DemoApp", "SDK error: $error")
    }
}

1.3 Przetwarzanie danych dotyczących zgody użytkowników

Sprawdzanie zgód użytkowników

Our SDK offer a unified method to check and retrieve consent information, getUserStatus() :
val status = cmpManager.getUserStatus()
Log.d("CMPDemo", "User Status: ${status.hasUserChoice}")
Log.d("CMPDemo", "TCF: ${status.tcf}")
Log.d("CMPDemo", "Additional Consent: ${status.addtlConsent}")
Log.d("CMPDemo", "Regulation: ${status.regulation}")

Log.d("CMPDemo", "---- Vendors Status ----")
status.vendors.forEach { (vendorId, choice) ->
    Log.d("CMPDemo", "Vendor $vendorId: $choice")
}

Log.d("CMPDemo", "---- Purposes Status ----")
status.purposes.forEach { (purposeId, choice) ->
    Log.d("CMPDemo", "Purpose $purposeId: $choice")
}

Więcej informacji na temat innych metod znajdziesz w naszej pełnej dokumentacji API

Ponowne otwarcie okna zgody w celu sprawdzenia wyborów użytkowników

Aby umożliwić użytkownikowi sprawdzenie lub zmianę swoich wyborów, wystarczy po prostu wywołać openConsentLayer()

cmpManager.forceOpen()

Ta metoda wyświetli warstwę zgody za pośrednictwem tej samej instancji WebView utworzonej w poprzednich krokach. 

Importowanie/eksportowanie informacji o zgodzie do innych źródeł

W niektórych przypadkach aplikacja natywna może zawierać widoki internetowe w celu wyświetlania informacji, takich jak reklamy lub treści. Aby przesłać informacje o zgodzie z SDK do widoku internetowego, możesz pobrać ciąg znaków zgody za pomocą:

consentData = cmpManager.exportCMPInfo()

Spowoduje to wyeksportowanie informacji o zgodzie oraz wszystkich dalszych danych potrzebnych CMP. Następnie możesz przekazać te informacje do CMP znajdującego się w Twoim widoku internetowym, dodając je do adresu URL wywoływanego w tym widoku.

Jeśli natomiast musisz zaimportować ciąg znaków zgody za pomocą SDK, możesz skorzystać z poniższego przykładu:

val consentStringToImport = "Q1FERkg3QVFERkg3QUFmR01CSVRCQkVnQUFBQUFBQUFBQWlnQUFBQUFBQUEjXzUxXzUyXzUzXzU0XzU1XzU2XyNfczI3ODlfczI3OTBfczI3OTFfczI2OTdfczk3MV9VXyMxLS0tIw"
cmpManager.importCMPInfo(consentStringToImport)

Tworzenie niestandardowego układu

Aby utworzyć dostosowany widok WKWebView, możesz stworzyć opakowanie dla ComponentActivity, które należy przekazać do CMP SDK, dzięki czemu uzyskasz pełną kontrolę nad jego wyglądem i cyklem życia. Więcej informacji znajdziesz w oficjalnej dokumentacji.

Logowanie

Korzystając z naszego SDK dla systemu iOS, możesz potrzebować debugowania lub analizy informacji z logów w różnych celach. Logi generowane przez nasze SDK są oznaczone tagiem „CMP”, co pozwala łatwo filtrować i wyświetlać tylko te logi, które są istotne. Więcej informacji znajdziesz w tej sekcji naszej dokumentacji.

Rozwiązywanie problemów

Class Not Found lub NoSuchMethodException:

ProGuard może czasami zaciemniać nazwy klas lub usuwać metody, do których odwołania są tworzone dynamicznie poprzez refleksję. Aby to naprawić, musisz w pliku konfiguracyjnym ProGuard określić klasy i metody, które powinny pozostać nienaruszone, używając -keep .

Przykładowa konfiguracja ProGuard pozwalająca zachować określoną klasę i jej metody:

# Kotlin serialization looks up the generated serializer classes through a function on companion
# objects. The companions are looked up reflectively so we need to explicitly keep these functions.
-keepclasseswithmembers class **.*$Companion {
    kotlinx.serialization.KSerializer serializer(...);
}
# If a companion has the serializer function, keep the companion field on the original type so that
# the reflective lookup succeeds.
-if class **.*$Companion {
  kotlinx.serialization.KSerializer serializer(...);
}
-keepclassmembers class <1>.<2> {
  <1>.<2>$Companion Companion;
}

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

-keepattributes JavascriptInterface

-keepclassmembers class net.consentmanager.sdk.common.callbacks.* {
   public *;
}

-keepclassmembers class net.consentmanager.sdk.consentlayer.ui.consentLayer.CmpWebView {
   public *;
}

-keepclassmembers class net.consentmanager.sdk.consentlayer.ui.CmpLayerAppInterface {
   public *;
}
-keep class net.consentmanager.sdk.CMPConsentTool {
                                                      *;
                                                  }

-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

-keepattributes JavascriptInterface

# Serializer for classes with named companion objects are retrieved using `getDeclaredClasses`.
# If you have any, uncomment and replace classes with those containing named companion objects.
#-keepattributes InnerClasses # Needed for `getDeclaredClasses`.
#-if @kotlinx.serialization.Serializable class
#com.example.myapplication.HasNamedCompanion, # <-- List serializable classes with named companions.
#com.example.myapplication.HasNamedCompanion2
#{
#    static **$* *;
#}
#-keepnames class <1>$$serializer { # -keepnames suffices; class is kept when serializer() is kept.
#    static <1>$$serializer INSTANCE;
#}

 

We do our best to keep this purely informative documentation up to date. However, if you notice that any of these guides need a little touch-up, let us know!