Informacia
Treść

[Android] 0. Przewodnik migracji

Ten przewodnik pomoże Ci przeprowadzić migrację z poprzedniej wersji CMP SDK do obecnej wersji. Omówimy zmiany w nazwach metod, parametrach i nowych lub wycofanych funkcjach. Przykłady aplikacji demonstracyjnych znajdziesz tutaj pod tym linkiem. Są dwa foldery, jeden z aplikacją demonstracyjną całkowicie opracowaną w Javie, zawierającą opakowanie dla Javy o nazwie JavaCMPManager inny całkowicie napisany w Kotlinie. 

Należy pamiętać, że ta wersja pakietu CMP SDK została całkowicie przebudowana od podstaw, dlatego stanowi ona istotna zmiana, ponieważ zmieniono nazwy wszystkich metod, zmieniono nazwy sygnatur, a teraz można też skorzystać z wywołań zwrotnych do niemal wszystkich metod. We wszystkich przypadkach, musisz zmodyfikować swój kod i zaktualizować zależności, aby upewnić się, że Twoja aplikacja mobilna działa zgodnie z oczekiwaniami. Warto również wspomnieć, że wszystkie dane zapisane przez poprzednią wersję naszego SDK na urządzeniach użytkowników zostaną usunięte, co zmusi aplikację do ponownie wyświetl warstwę zgody.

Repozytoria

Należy pamiętać, że wszystkie nasze repozytoria zostały zmienione dla Android SDK. Postępuj zgodnie z poniższymi instrukcjami, aby dowiedzieć się, gdzie skierować swojego menedżera zależności. 

Maven

W pliku Gradle zamień poprzedni wiersz na poniższy:

implementation("net.consentmanager.sdkv3:cmsdkv3:3.2.0")

Po dokonaniu zmiany zsynchronizuj projekt. 

Kluczowe punkty migracji

  1. Wzór delegata: Zamiast pojedynczych słuchaczy nowa wersja wykorzystuje pojedynczy protokół delegata (CMPManagerDelegate) do obsługi zdarzeń. Zawiera 4 główne zdarzenia:
    1. didReceiveConsent(consent: String, jsonObject: Map<String, Any>)
      Wyzwala się, gdy warstwa zgody została zamknięta po zaktualizowaniu przez użytkownika swoich zgód LUB podczas wywołania metod powodujących zmiany w zgodach, takich jak acceptAll, rejectAll, acceptVendors, rejectVendors itd. Oznacza to, że użytkownik zaakceptował lub odrzucił część lub wszystkie zgody, a także że zostały one prawidłowo zapisane na urządzeniu.
    2. didShowConsentLayer
      Wyzwala się, gdy warstwa zgody została faktycznie wyświetlona. Oznacza to, że w urządzeniu nie było ważnej zgody, więc należy zebrać nową.
    3. didCloseConsentLayer
      Wyzwalane jest, gdy SDK sprawdza potrzebę zgody, ale nie była ona potrzebna i warstwa nie była wyświetlana. Oznacza to, że w urządzeniu jest już prawidłowa, więc nowa nie jest konieczna i warstwa zgody nie zostanie wyświetlona.
    4. didReceiveError
      Wyzwalane jest to w przypadku, gdy operacja SDK zgłosi błąd.
  2. Osoby odpowiedzialne za realizację: Wiele metod obejmuje teraz obsługę ukończenia dla operacji asynchronicznych. Zaktualizuj swój kod, aby odpowiednio obsługiwać te wywołania zwrotne.
  3. Ciąg zgody: Zastosowanie exportCMPInfo() zamiast getConsentString() aby pobrać informacje o zgodzie.
  4. Zgody na dostawcę i cel: Metody uzyskiwania zgód dostawcy i celu zwracają teraz tablice identyfikatorów. Może być konieczne dostosowanie logiki do obsługi tych tablic.
  5. Łańcuch prywatności w USA: Kolekcja getUSPrivacyString() metoda została wycofana. Jeśli używałeś jej w celu zachowania zgodności z CCPA, pamiętaj, że ta metoda nie jest już dostępna.
  6. Weryfikacja wymogu zgody: Użyj nowego checkAndOpen(completion:) metoda automatycznego określania, czy zgoda jest wymagana przed wyświetleniem warstwy zgody.

Zmiany metod i podpisów

Inicjalizacji
  • Stary: CmpManager.initialize(context: Context, cmpConfig: CmpConfig)
  • Nowość: CmpManager.createInstance(context: Context, cmpConfig: CmpConfig)
Ustaw konfigurację interfejsu użytkownika
  • Stary: .withCmpViewControllerConfigurationBlock { ... }
  • Nowość: Opcja ta nie jest dostępna, ale możesz utworzyć aktywność opakowującą i kontrolować cykl życia oraz wygląd kodu po swojej stronie.
Sprawdzanie zgody
  • Stary: check({ ... }, isCached: Bool),
  • Nowość: checkAndOpen(completion: (Error?) -> Void)
Sprawdzanie i otwieranie warstwy zgody, jeśli to konieczne
  • Stary: checkAndOpenConsentLayer()
  • Nowość: checkAndOpen(completion: (Error?) -> Void)
  • Stary: openConsentLayer()
  • Nowość: forceOpen(completion: (Result<Unit>) -> Unit)
Zaakceptuj wszystkie zgody
  • Stary: acceptAll(callback: ConsentCallback)
  • Nowość: cceptAll(completion: (Result<Unit>) -> Unit)
Odrzuć wszystkie zgody
  • Stary: rejectAll(onFinish: () -> Unit)
  • Nowość: rejectAll(completion: (Result<Unit>) -> Unit)
Włącz cele
  • Stary: enablePurposeList(purposes: List<String>, updateVendor: Boolean, onConsentReceivedCallback: OnConsentReceivedCallback?)
  • Nowość: acceptPurposes(purposes: List<String>, updatePurpose: Boolean, completion: (Result<Unit>) -> Unit)
Wyłącz cele
  • Stary: disablePurposeList(purposes: List<String>, updateVendor: Boolean, onConsentReceivedCallback: OnConsentReceivedCallback?)
  • Nowość: rejectPurposes(purposes: List<String>, updateVendor: Boolean, completion: (Result<Unit>) -> Unit)
Włącz dostawców
  • Stary: enableVendorList(vendors: List<String>, onConsentReceivedCallback: OnConsentReceivedCallback?)
  • Nowość: acceptVendors(vendors: List<String>, completion: (Result<Unit>) -> Unit)
Wyłącz dostawców
  • Stary: disableVendorList(vendors: List<String>, onConsentReceivedCallback: OnConsentReceivedCallback?)
  • Nowość: rejectVendors(vendors: List<String>, completion: (Result<Unit>) -> Unit)
Zdobądź wszystkie cele
  • Stary: getAllPurposes(): List<String>
  • Nowość: getAllPurposesIDs(): List<String>
Uzyskaj włączone cele
  • Stary: getEnabledPurposes(): List<String>
  • Nowość: getUserStatus(): UserConsentStatus
Uzyskaj wszystkich dostawców
  • Stary: getAllVendors(): List<String>
  • Nowość: getUserStatus(): UserConsentStatus
Uzyskaj włączonych dostawców
  • Stary: getEnabledVendors(): List<String>
  • Nowość: getUserStatus(): UserConsentStatus
Sprawdź cel zgody
  • Stary: hasPurposeConsent(String): Boolean
  • Nowość: getStatusForPurpose(id: String): ConsentStatus
Sprawdź zgodę dostawcy
  • Stary: hasVendorConsent(String): Boolean
  • Nowość: getStatusForVendor(id: String): ConsentStatus
Eksportuj ciąg CMP
  • Stary: exportCmpString() : String
  • Nowość: exportCMPInfo(): String
Importuj ciąg CMP
  • Stary: importCmpString(consentString: String, completionHandler: ((Error?) -> Unit)?)
  • Nowość: importCMPInfo(cmpString: String, completion: (Result<Unit>) -> Unit)
  • Stary: reset()
  • Nowość: resetConsentManagementData(completion: (Result<Unit>) -> Unit)
Radzenie sobie ze statusem trybu zgody Google
  • Stary: withGoogleAnalyticsCallback(analyticsListener: CmpGoogleAnalyticsInterface)
  • Nowość: getGoogleConsentModeStatus
Radzenie sobie z wywołaniem zwrotnym onLinkClick
  • Stare: v2 miała funkcję białej listy. W obecnej wersji proces został uproszczony, a użytkownik ma pełną kontrolę nad zachowaniem, które należy wykonać zgodnie z adresem URL zwróconym z metody.
cmpConfig.domainWhitelist = ["add your domains to be whitelisted"]

cmpManager.withOnCmpLinkClickListener({ url, decisionHandler in
//check URL and add the nav action
decisionHandler!.pointee = WKNavigationActionPolicy.allow
decisionHandler!.pointee = WKNavigationActionPolicy.cancel
// return shouldCloseWebView (true) or stay open (false)
return true
})
  • Nowość: Użytkownik ma pełną kontrolę nad tym, jakie zachowanie ma być stosowane zgodnie z adresem URL. Zatem poprzednie białe listy adresów URL powinny zostać przeniesione do metody wywołania zwrotnego,
cmpManager.setLinkClickHandler { url in
    // Handle links to specific domains externally. The user has full control over which behavior to follow
    // according to the URL. The previous whitelisted URL's should be migrated to inside the callback method, 
    // and the user has the choice to use a switch-case statement, pattern matching, etc.
    if url.host?.contains("google.com") == true || 
       url.host?.contains("facebook.com") == true {
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
        return true // URL handled externally
    }
    
    // Let other URLs load in the WebView
    return false
}

 

Metody przestarzałe:

  • checkIfConsentIsRequired(completion: @escaping (Bool) -> Void)
  • hasUserChoice() -> Bool

  • hasPurposeConsent(id: String) -> Bool

  • hasVendorConsent(id: String) -> Bool

  • openConsentLayer(completion: @escaping (NSError?) -> Void)

  • getAllPurposesIDs() -> [String]

  • getEnabledPurposesIDs() -> [String]

  • getDisabledPurposesIDs() -> [String]

  • getAllVendorsIDs() -> [String]

  • getEnabledVendorsIDs() -> [String]

  • getDisabledVendorsIDs() -> [String]

  • getUSPrivacyString()
  • calledThisDay(): Boolean
  • getConsentstring(): String
  • getGoogleACString(): String
  • getUSPrivacyString(): String
  • initialize(context: Context, cmpConfig: CmpConfig)
  • setCallbacks(...)
  • withGoogleAnalyticsCallback(analyticsListener: CmpGoogleAnalyticsInterface)

Przykłady migracji

Kotlin

// ============================================
// Previous versions
// ============================================

class CmpDemoActivity : FragmentActivity() {

    private lateinit var cmpManager: CmpManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        val config = CmpConfig.apply {
            id = "<YOUR-CONSENTMANAGER-APP-ID>" // example: b238acdf1a
            domain = "<YOUR-CONSENTMANAGER-APP-DOMAIN>" // example: delivery.consentmanager.net
            appName = "<YOUR-CONSENTMANAGER-APP-NAME>" // example: testApp
            language = "<YOUR-CONSENTMANAGER-APP-LANGUAGE>" // example: DE
        }
        
        cmpManager = CmpManager.createInstance(this, config)
        cmpManager.initialize(this)
    }
}
// ============================================
// SDK v3 implementation
// ============================================
                                           
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()

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

        // This UI Config for Android is limited, but you have the option to create an activity wrapper
        // to have full control over the appearance and the position
        val webViewConfig = ConsentLayerUIConfig(
            position = ConsentLayerUIConfig.Position.FULL_SCREEN, // that's the only position available for Android
            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.checkWithServerAndOpenIfNecessary { 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")
    }
}

Java 

// ===================================================
// Previuous versions
// ===================================================

public class CmpDemoActivity extends AppCompatActivity {

    private CmpManager cmpManager;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        CmpConfig cmpConfig = CmpConfig.INSTANCE;
        cmpConfig.setId("<YOUR-CONSENTMANAGER-APP-ID>"); // example: a000aaaa1a
        cmpConfig.setDomain("<YOUR-CONSENTMANAGER-APP-DOMAIN>"); // example: delivery.consentmanager.net
        cmpConfig.setAppName("<YOUR-CONSENTMANAGER-APP-NAME>"); // example: testApp
        cmpConfig.setLanguage("<YOUR-CONSENTMANAGER-APP-LANGUAGE>"); // example: EN
        cmpConfig.setTimeout(4000);

        cmpManager = CmpManager.createInstance(this, cmpConfig);
        cmpManager.initialize(this)
    }
}

// ===========================================
// SDK v3 implementation
// ===========================================

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cmp_demo);

        UrlConfig urlConfig = new UrlConfig(
                "09cb5dca91e6b",
                "delivery.consentmanager.net",
                "EN",
                "CMDemoAppJava"
        );

      // This UI Config for Android is limited, but you have the option to create an activity wrapper
      // to have full control over the appearance and the position

        ConsentLayerUIConfig webViewConfig = new ConsentLayerUIConfig(
                ConsentLayerUIConfig.Position.FULL_SCREEN,
                ConsentLayerUIConfig.BackgroundStyle.dimmed(Color.BLACK, 0.5f),
                10f,
                true,
                false
        );

        JavaCMPManager cmpManager = JavaCMPManager.getInstance(this, urlConfig, webViewConfig, this);
        cmpManager.setActivity(this);

        cmpManager.checkAndOpen(result -> {
            if (result.isSuccess()) {
            } else {
                Log.e("JavaDemoAp", "Initialize method failed with error: " + result.exceptionOrNull());
            }
            return null;
        });
    }

    private void showCMPDemoScreen() {
        Intent intent = new Intent(this, CMPDemoActivity.class);
        startActivity(intent);
        finish();
    }

    @Override
    public void didShowConsentLayer() {
        Log.d("CMP JavaDemoAp", "Consent Layer open message received.");
    }

    @Override
    public void didCloseConsentLayer() {
        Log.d("CMP JavaDemoAp", "Consent Layer close message received.");
    }

    @Override
    public void didReceiveError(@NonNull String error) {
        Log.e("CMP JavaDemoAp", "SDK error: " + error);
    }

    @Override
    public void didReceiveConsent(@NonNull String consent, @NonNull Map<String, Any> jsonObject) {
        Log.d("CMP JavaDemoAp", "Consent received: " + consent);
        runOnUiThread(this::showCMPDemoScreen);
    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {
        super.onPointerCaptureChanged(hasCapture);
    }

    @Override
    public void addMenuProvider(@NonNull MenuProvider provider, @NonNull LifecycleOwner owner, @NonNull Lifecycle.State state) {

    }
}

 

Powrót do góry