[Android] 1. Integration des Consentmanager-SDK

In diesem Dokument finden Sie allgemeine Informationen zur Integration unseres SDK in Ihr Projekt. Weitere Details entnehmen Sie bitte unserer API-Referenzdokumentation. Alle folgenden Codeausschnitte stammen aus unserer Demo-App

1. Installation

Das ConsentManager SDK ist eine umfassende Lösung zur Verwaltung der Nutzerzustimmung in mobilen Anwendungen. Dieses SDK wurde entwickelt, um die Einhaltung der DSGVO, die Datenschutzpräferenzen der Nutzer und die Transparenz beim Ad-Tracking zu gewährleisten, und bietet eine nahtlose Integration für iOS- und Android-Plattformen. Darüber hinaus bietet es Wrapper-Plugins/Bridges für React Native, Flutter und Unity, wodurch es in verschiedenen Entwicklungsumgebungen vielseitig einsetzbar ist.

Schritte – Allgemeine Beschreibung

  1. Integration und Konfiguration:

    • Integrieren Sie das SDK in Ihre App.
    • Konfigurieren Sie die SDK-Einstellungen entsprechend Ihren Anforderungen.
  2. Erstellen einer Instanz und Anzeigen der Einwilligungsschicht:

    • Erstellen Sie beim Start der App eine Instanz der CMPManager Klasse. Diese Instanz übernimmt den Einwilligungsprozess.
    • Das SDK zeigt den Einwilligungsbildschirm bei Bedarf automatisch an.
  3. Verarbeitung der Einwilligungsdaten der Nutzer:

    • Sobald die Einwilligungen erfasst sind, werden die Informationen gespeichert und können über verschiedene Eigenschaften und Methoden, die unser SDK bereitstellt, abgefragt werden. Du erhältst Informationen über abgelehnte oder akzeptierte Einwilligungen, Anbieter und Zwecke.

1.1 Integration und Konfiguration

Hinzufügen einer Abhängigkeit über Gradle

Fügen Sie die folgende Zeile zu Ihrer build.gradle-Datei hinzu:

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

Synchronisieren Sie anschließend Ihr Projekt. 

1.2 Instanz erstellen und Einwilligungslayer anzeigen

Innerhalb der App-Start-Funktion onCreate Funktion) musst du eine Instanz der Klasse CMPManager. Du musst zwei Objekte einrichten, die an die getInstance-Methode übergeben werden: UrlConfig, das Ihre CMP-Konfiguration wie Code-ID und Standardsprache verwaltet, und ConsentLayerUIConfig. die das Aussehen der WebView konfiguriert, in der die Einwilligungsschicht angezeigt wird. Danach übergeben Sie die aktuelle Activity mit der Methode setActivityund dem Delegaten zuweisen, wie unten gezeigt. Im folgenden Beispiel finden Sie beide übergebene Objekte. Die checkAndOpen() Funktion ruft automatisch die erforderlichen Daten von unserem Server ab und ermittelt, ob der Einwilligungsbildschirm angezeigt werden muss oder nicht. Ist dies der Fall, zeigt das SDK an dieser Stelle automatisch den Einwilligungsbildschirm über ein WebView von unserem SDK erstellten Popup, das die Einwilligungsmaske mit dem Text und den Schaltflächen gemäß Ihren CMP-Konfigurationen (ausgewählt über die Code-ID Ihres CMP) anzeigt, die Daten erfasst und die Einwilligungsinformationen im NSUserDefaults-Bereich des Geräts speichert, damit die App die gezielten Anzeigen entsprechend anzeigen kann. 

Bitte beachten Sie, dass es unerlässlich ist, das CMPManager SDK in der onCreate Methode zu deklarieren und zu initialisieren, da die Ansicht sonst möglicherweise nicht einsatzbereit ist und das SDK fehlschlagen könnte. Bitte beachten Sie auch das Singleton-Muster, damit Sie nur eine Instanz des SDK haben. Stellen Sie außerdem sicher, dass Sie die richtigen Konfigurationsdaten verwenden. Die Konfigurationsdaten finden Sie in Ihrem ConsentManager-Konto unter Menü > CMPs > Code für Apps abrufen > Code-ID

Beachten Sie bitte auch, dass die Funktionen zur Feststellung, ob eine Einwilligung erforderlich ist oder nicht, sowie die Anzeige des Einwilligungsfensters von einer zuverlässigen Netzwerkverbindung abhängen. Wenn keine Verbindung verfügbar ist oder der Wiederholungsmechanismus unseren Server nicht erreichen kann, gibt das didReceiveError-Ereignis einen Timeout-Fehler zurück, sodass das SDK die Notwendigkeit einer Einwilligung überhaupt nicht feststellen kann, da es die Einwilligungsmaske nicht anzeigen kann. Bitte stellen Sie sicher, dass Ihre Logik dies berücksichtigt.

Beispiel:

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 Verarbeitung der Einwilligungsdaten der Nutzer

Überprüfung der Einwilligungen der Nutzer

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")
}

Weitere Informationen zu den anderen Methoden finden Sie in unserer vollständigen API-Dokumentation

Erneutes Öffnen der Einwilligungsschicht, um die Auswahl der Nutzer zu überprüfen

Damit der Nutzer seine Auswahl überprüfen oder ändern kann, können Sie einfach openConsentLayer()

cmpManager.forceOpen()

Diese Methode zeigt die Einwilligungsschicht über dieselbe WebView-Instanz an, die in den vorherigen Schritten erstellt wurde. 

Importieren/Exportieren von Einwilligungsinformationen in andere Quellen

In einigen Fällen kann eine native App Webviews enthalten, um Informationen wie Werbung oder Inhalte anzuzeigen. Um die Einwilligungsinformationen vom SDK an den Webview zu übermitteln, können Sie die Einwilligungszeichenfolge wie folgt abrufen:

consentData = cmpManager.exportCMPInfo()

Dadurch werden die Einwilligungsinformationen und alle weiteren Daten exportiert, die von der CMP benötigt werden. Du kannst diese Informationen dann an die CMP in deiner Webview weiterleiten, indem du sie der URL hinzufügst, die in der Webview aufgerufen wird.

Falls du die Einwilligungszeichenfolge stattdessen über das SDK importieren musst, kannst du das folgende Beispiel verwenden:

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

Erstellen eines benutzerdefinierten Layouts

Um eine angepasste Ansicht der WKWebView zu erstellen, können Sie einen Wrapper für die ComponentActivity erstellen, die an das CMP SDK übergeben werden muss, sodass Sie die volle Kontrolle über das Erscheinungsbild und den Lebenszyklus dieser Komponente haben. Weitere Informationen finden Sie in der offiziellen Dokumentation.

Anmeldung

Wenn Sie unser iOS-SDK verwenden, kann es vorkommen, dass Sie aus verschiedenen Gründen Log-Informationen debuggen oder analysieren müssen. Die von unserem SDK generierten Logs sind mit dem Tag „CMP“ versehen, sodass Sie die relevanten Logs leicht filtern und anzeigen können. Weitere Informationen finden Sie in diesem Abschnitt unserer Dokumentation.

Fehlerbehebung

Klasse nicht gefunden oder NoSuchMethodException:

ProGuard kann manchmal Klassennamen verschleiern oder Methoden entfernen, auf die dynamisch über Reflection verwiesen wird. Um dies zu beheben, müssen Sie die Klassen und Methoden, die intakt bleiben sollen, in der ProGuard-Konfigurationsdatei mithilfe der -keep angeben.

Beispiel für eine ProGuard-Konfiguration, um eine bestimmte Klasse und ihre Methoden beizubehalten:

# 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!