Android — Versions
Cette page est maintenue en anglais — une seule source évite qu'une traduction dérive de la réalité du SDK à chaque release.
All notable changes to the Android SDK. Entries are newest first.
Sections follow the same headings throughout: Features for new or changed behaviour, Fixes for corrections, Requirements at the end. Breaking changes are called out in their own block at the top of the entry.
Maintainers: a new entry is dated on the day the version is actually published, not when it is written. An entry marked
(unreleased)has not been tagged yet — see the release checklist.
Next release (unreleased)
Fixes
When the configuration could not be loaded, the consent screen says so. It showed the banner with the default theme and empty lists; it now shows a message and a Close button, like iOS. The back button closes it without reporting a close.
2.0.0 (2026-10-05)
Published on Maven Central, like 1.2.0. The version number moves to 2.0.0 on every channel at once, because the iOS SDK opens its CocoaPods channel with it.
Breaking changes
ConsentButtonStyle.CLOSEis removed from the consent UI's publicConsentButtonStyleenum. The "Close link" refusal style is now rendered as a link in the banner header, which left the value without a use.scopeReminderOpensHostnamesis removed from the consent UI's publicConsentUiState, which gainsscopeReminderSegmentsandpurposesText2Segments. The scope reminder now carries its links as segments, each opening its own target, instead of making the whole text one tap target. Unlike the data classes below, no overload keeps the previous constructor orcopyofConsentUiState.Four public data classes gain a field:
GoogleConsentState.adSignalsFromTcf,UserAction.page_view_id,Settings.sirdataRestrictionsandInfo.lastUpdate. Their previous constructor andcopysignatures are kept as overloads, so source code is unaffected; code compiled against 1.2.0 that calls them with default arguments must be recompiled.
Features
The consent adapters forward each choice to Firebase Analytics, AppsFlyer, Adjust and Branch. Measured against the latest version of each SDK, none of the four received it correctly in 1.2.0, and nothing said so: the AppsFlyer and Branch adapters called APIs that have moved or do not exist, the Adjust adapter turned measurement off after an "Accept all", and in a minified release build the Firebase adapter sent nothing. A failing adapter is now logged under its name, on the
SirDataCMPLogcat tag; only an absent SDK stays silent. See Sharing consent with vendor SDKs.The SDK ships its R8 rules. A minified release build no longer fails on
org.slf4j.impl.StaticLoggerBinder, and the adapters survive shrinking: the rules you added for the SDK can go."TCF/Google Consent Mode Interoperability" (
consentModeFromTcf) behaves as on the web. The SDK writesIABTCF_EnableAdvertiserConsentMode= 1,pingandgetTCDatacarryenableAdvertiserConsentMode: true, and Firebase Analytics receivesanalytics_storageonly, so that it derives the three ad signals from the TC string. 1.2.0 sent those three asdenied, whatever the user chose.Publisher restrictions are applied. The consent UI no longer asks a partner for a purpose the publisher forbids it, the TC string and the
IABTCF_PublisherRestrictions{ID}keys carry the restrictions, and the signals sent to Google through Firebase and AppsFlyer take them into account.The Sirdata consent string carries the restrictions the configuration applies to Sirdata partners, and the version of the Sirdata list it was built from (it always said 1).
The three non-versioned lists (Global Vendor List, Sirdata list, Google Additional Consent providers) are requested with the visitor's country, when it is known, so the API can filter them.
The consent archive carries the country and the revision of the configuration that was displayed. Every hit carries a
page_view_id, drawn once perinitialize(), so the load, the clicks and the answer of one display share it.The banner's refusal button follows the publisher's style as the web does. "Close link" puts the refusal label in the header, in place of the close cross (it was a discreet text button next to the other buttons); "Big button (secondary color)" is outlined like "Customize my choices" (it was a solid grey block); "Big button (main color)" looks exactly like "Accept all" (it was drawn at 70 % opacity). The manual re-opening shows a "Reject all" button whatever the refusal type and style, with the close cross at the top; it showed no refusal at all.
The publisher's text size scales the consent UI by the web's ratios, 12/13 and 14/13 for "small" and "large" (about ±7.7 %), instead of ±15 %.
The purposes and partners screens carry the links of their scope reminder, as on the web: the list of the sites the consent covers, and the Consent Framework site.
Outside the US screen, the close button that saves nothing reports its answer,
response:close, along with its click,ui:close, as the web does; 1.2.0 sent the click alone. The US screen's close button still reportsccpa_response:closealone. Under the CNIL variant, where the close button saves the choice, nothing changes.The system back button is reported like the close button that saves nothing (
response:closeandui:close, orccpa_response:closeon the US screen). It already closed the banner, without any report.isGdprApplies()and the in-app TCF API returncontext.gdprAppliesas served by the API; the SDK no longer addsforceGdpron top of it. The server already foldsforceGdprinto that value, so what an integrator sees does not change.
Fixes
The SDK no longer fails to start on a configuration that serves publisher restrictions. The API serves
restrictionTypeas a number, which 1.2.0 could not decode:initialize()failed and the CMP never loaded.Toggling a stack records only the members the screen shows, and a purpose row records only the legal bases the served list asks for. Both could record a consent or a legitimate interest the user was never asked for.
Utils.buildAddtlConsentreturns the string the SDK stores inIABTCF_AddtlConsent, prefixed2~. It returned a1~string that no device ever stored.In dark mode, a logo or watermark set to "no image" no longer displays the word
NONE, and an empty dark-mode image falls back to the light-mode one, as on the web.
Requirements
Android API 23 (6.0) or higher,
compileSdk34, Kotlin 1.9.22 or higher; verified with Android Gradle Plugin 8.2.2 on JDK 17. See Setup — Android, step 1.
1.2.0 (2026-09-23)
First public release of the Android SDK. Earlier version numbers exist in the repository history but were never resolvable by an integrator: no artifact had been published under com.sirdata.cmp on Maven Central, so this entry is the starting point of the public history rather than a delta.
Breaking changes
Two public symbols are removed. Neither has ever been reachable from a published artifact — nothing had been published under
com.sirdata.cmp— so this is announced for the record rather than as a migration:TcStringEncoder.convertTcStringToGppString(tcString). It built a GPP string carrying the TCF section alone, which stopped being the production path when the SDK started emitting the US National section: the GPP string andIABGPP_GppSIDare now assembled together from one section list. ReadingIABGPP_HDR_GppStringis the supported way to obtain it.Context.isAskLaterCappingActive(store). A dead duplicate of the "ask later" capping rule, and it used a different window from the live one —context.cappingInHoursinstead of the fixed one hour. The rule the SDK actually applies is internal to the display cascade; callawaitConsentDisplayDecision()to ask whether the banner should be shown.
Features
The main-thread contract of
initialize,shutdownandsetCcpaOptOutis enforced rather than only documented. The three read and re-encode the consent state — jurisdiction, configuration and store — together and without a lock, so calling them from a background thread is a race. Off the main thread the SDK now logs the violation, naming the entry point; declaredebugMode(true)on the configuration and it throws instead, so the fault surfaces in your own debug build rather than as a rare, silent race in production.debugModehas no other effect.IAB TCF v2.2 in-app CMP API (registered CMP ID 92), IAB GPP and CCPA/USP support. All signals are written to
SharedPreferencesunder the standard IAB keys, so compliant vendor SDKs read consent with no integration code.Native Jetpack Compose consent UI: banner, purposes and partners screens, themed from the publisher configuration.
Display cascade ported from the web CMP —
awaitConsentDisplayDecision()decides whether and how to present the UI, covering partial consent, capping windows and the cookie wall.MANUAL_DISPLAYandAPPLY_CHOICESworkflows for re-opening the UI from a settings screen and for asking only what is left to decide.Google Additional Consent string and Google Consent Mode state derived from TCF purposes, with consent adapters for automatic forwarding.
The consent UI does not list a partner for which the user has no decision to make — a partner with neither a consent nor a legitimate-interest toggle.
50 languages — every locale the Sirdata API serves. BCP 47 tags are matched with their full label and case-insensitively, the way
Locale.toLanguageTag()actually reports them, andnb-NO/nn-NO/fil-PHresolve to Norwegian and Filipino through an alias table.Right-to-left languages render right-to-left. The consent UI sets its own layout direction from the banner's language instead of inheriting the host app's — LTR as explicitly as RTL, which is what closes the inheritance for the 48 left-to-right languages.
In the "apply choices" workflow, the refusal button is not rendered when the publisher set the no-consent button to
NONE— that is, when they explicitly chose not to offer a refusal on the banner.forceGdpris the single supported way to override GDPR applicability. The overlappingsetGdprAppliescommand was removed before this first release, so it never reached an integrator.GPP US National (section 7) is emitted alongside the deprecated
uspv1section, andIABGPP_GppSIDis built from the same section list as the string rather than derived from it — it used to be read back out of a Fibonacci-encoded header, which cannot work, so it never announced anything but2.The publisher configuration is now fetched from the
cacheApiRoothost (choices.consentframework.comby default) rather thanapiRoot(api.consentframework.com). Both hosts serve the same endpoint, and the two responses were compared key by key: 614 keys against 615, no differing value, the single extra key being thecontext.regionthat onlychoicescan carry — it sits behind the CDN that resolves the visitor's country and US state, which the US National section needs. Integrators who pin hosts in a network allowlist, a proxy rule or a certificate-pinning configuration should confirmcacheApiRootis reachable — the other two hosts are unchanged, and all three remain configurable.getUspString()returns an empty string when no opt-out decision has been recorded."1---"is not a neutral default: the US Privacy spec makes it an explicit assertion that the consumer falls outside a US Privacy jurisdiction. The sale opt-out itself is recorded under its own key, so a value fabricated by an earlier SDK version can never be mistaken for a decision the user made.
Fixes
pingreports the undetermined state until the publisher configuration is loaded, instead of a default determination the CMP had not computed.The library declares its
material-icons-coredependency explicitly. It used to arrive transitively through the Compose BOM's material3; apps resolving a newer material3 — which no longer carries the icons — crashed withNoClassDefFoundErroron the purposes screen and on the manual-display close button.The library declares the
INTERNETandACCESS_NETWORK_STATEpermissions in its own manifest, so integrators get them through manifest merging. An app withoutINTERNETpreviously crashed on first launch instead of degrading.removeEventListeneraccepts a boxedLong, which is what a Java caller passes naturally (Long.valueOf(id)). It previously fell through to the null branch and the listener was never removed.pingandgetTCDataread the TCF policy version and GDPR applicability through the same storage reader, so the two commands can no longer report different values in the same session.
Requirements
Android API 23 (6.0) or higher, Kotlin 1.9.22 or higher.
Mis à jour
Ce contenu vous a-t-il été utile ?
