Repository navigation
Releases: axeptio/native-android-sdk
Release list
Axeptio SDK 1.3.0
Breaking
The SDK has no integrations in production yet, so 1.3.0 cleans up the public API instead of waiting for a 2.0.0.
- Query callbacks on the main thread:
getRemainingDaysForConsent,getAxeptioToken,getBrandsVendorConsents,getTcfTcStringandgetTcfVendorConsentscall back on the main thread instead ofDispatchers.IO, like the event listener and the iOS SDK. TheSdkNotInitializedExceptionfailure is posted there too instead of being delivered on the calling thread. Remove main-thread switches around them and move blocking work out of the callbacks. AxeptioLogLevelmoved fromio.axeptio.sdk.modeltoio.axeptio.sdk.configuration.- Internal configuration types are no longer exposed:
io.axeptio:foundation-core-configis off the app's compile classpath. UseAxeptioEnvironment,AxeptioService,AxeptioPermissionandAxeptioLogLevelfromio.axeptio.sdk.configuration. - Removed:
AxeptioConfigBuilder.withPermissions(...)that took the foundationAxeptioPermission. Importio.axeptio.sdk.configuration.AxeptioPermission; the call stays the same.- The 1.0.1 binary-compatibility permission accessors. Recompile against 1.3.0.
- The deprecated Koin module values (
coreDataStoreModule,hostModule,featureConsentsModule,featurePermissionsModule,dataConfigurationModule,dataPermissionsModule,dataAnalyticsModule). Call the matching…Module()functions. - The unused
io.axeptio.foundation.data.configuration.model.consents.ConsentRecord.
- Java:
get/set/withSdkPermissions()onAxeptioConfigBuilderare nowget/set/withPermissions().- The Kotlin-only forms are hidden from Java and have Java replacements (see Added): the lambda
initialize, theResultcallbacks and the suspendclearConsentData.
Added
- Google Consent Mode v2:
AxeptioEventListener.onGoogleConsentModeUpdate(GoogleConsentV2)andAxeptioSDK.getGoogleConsentMode, both on the main thread, forFirebaseAnalytics.setConsent.GoogleConsentType/GoogleConsentStatususe Firebase's names.- TCF derives the signals from the purpose consents, like the web CMP.
- Brands: "Accept all" grants all four signals. "Refuse all" and saved choices deny them.
- With Consent Mode on, each launch reports the stored consent's signals, or all four denied without a valid consent, and
clearConsentData()reports them denied. - TCF configurations with Consent Mode on also set
IABTCF_EnableAdvertiserConsentMode.
- Java support:
- Every
AxeptioSDKmember is static. initialize(Context, AxeptioConfigBuilder).AxeptioCallback<T>overloads for every query and forclearConsentData.observeConsentStatus(LifecycleOwner, ConsentStatusListener).- Constructor overloads on
AxeptioPermissionandAxeptioError.ConsentSyncFailed.
- Every
Changed
- The SDK now exposes
androidx.activity:activity,androidx.lifecycle:lifecycle-commonandkotlinx-coroutines-coreas API dependencies, because their types appear in its public API. - The public API of every published module is checked in CI.
Fixed
- Google Consent Mode on TCF configurations: it was always read as off.
- Back button:
- A quick double back from a details screen no longer closes the consent flow without a choice.
- A back while the consent and permission steps change no longer closes the SDK.
- TCF first-layer card text: the first card no longer doubles its preposition ("Sur Sur cette application") in 20 languages. Hungarian, Polish and Latvian are unchanged and still need a reworded translation.
Axeptio SDK 1.3.0-beta.1
Added
- data: derive Google Consent Mode v2 signals per flow
- data: keep and sync a Brands consent's Google Consent Mode signals
- sdk: add the Google Consent Mode v2 public model
- sdk: report Google Consent Mode v2 signals to the host
- sample: show the Google Consent Mode signals
- data: deny the Consent Mode signals at launch without a valid consent
- tcf: set IABTCF_EnableAdvertiserConsentMode with Consent Mode on
- sdk: make the public API usable from Java [ENG-13512]
- sdk: give the permission constructors Java overloads [ENG-13512]
Changed
- sample: target API 36 in publicSample on SDK 1.2.0
- claude: allow public API changes before the first customer
- sdk: clean up the public API before launch
- configuration: remove the unused public ConsentRecord [nasdk-6if.20]
- configuration: sample the TCF retry snapshot once and gate it [nasdk-6if.21]
- document Google Consent Mode v2 and its emulator tests
- emulator-tests: let EMU-051 relaunch once the consent is synced
- qualify the Firebase TCF note and the sample's empty signals
- emulator-tests: reflow the lines the rebase lengthened
- data: say why the launch replays the stored Consent Mode signals
- readme: import the Android types of the Java snippets [ENG-13512]
- readme: update the setup and the 2.x mapping for 1.3.0
Fixed
- ci: skip publicSample in the pre-commit coverage check
- ci: reject breaking markers in commit messages before launch
- consents: swallow a back that reaches the graph with the first layer alone
- design-system: start TCF card 1 with the on-this-app phrase [ENG-13512]
- host: a back while a step slides in no longer closes the SDK [nasdk-akh]
- data: read the Brands Consent Mode signals against one snapshot
- data: answer the Consent Mode signals while the vendor list loads
- data: withdraw the Consent Mode signals after a partly failed clear
- tcf: keep IABTCF_EnableAdvertiserConsentMode in step with the configuration
- tcf: read the Consent Mode of the TC string write when it runs
- sdk: export the libraries of the public API types [ENG-13512]
- sdk: address the callback KDoc and the lifecycle test review [ENG-13512]
Axeptio SDK 1.2.0
Added
- Host events:
AxeptioSDK.setEventListener(AxeptioEventListener?)/removeEventListener(), withonConsentFlowClosed(),onConsentsUpdated()andonError(AxeptioError), delivered on the main thread.onErrorreports consent sync give-ups (ConsentSyncFailed), configuration, vendor-list and user-token failures, and unexpected internal errors. - Configuration fields from the Axeptio back office:
askNewConsent, the TCF purposes and stacks a configuration selects, and the consent lifetime (expirationTtlDays). - Re-prompt and consent lifetime like the web CMPs: a new CMP version asks for a new consent only when the configuration says so, and each consent keeps the lifetime it was saved with.
Changed
- TCF accept-all consents every purpose and special feature of the TCF catalog and puts every purpose but 1 and 3-6 under legitimate interest, like the web CMP and the iOS SDK. The consent screens list the configured purposes and stacks.
- TCF vendor details follow the iOS SDK: storage duration, the legitimate-interest link in the consent language, data categories without unnamed ids, and the small vendor icon first.
- Analytics events match the iOS SDK: sorted preferences, millisecond timestamps, a browser-like user agent, and retries 10 s apart. Events are tagged with the flow the configuration resolved to, and the queue is kept out of Auto Backup.
- Network: only network errors and 5xx responses are retried; the user-token request is retried like on iOS.
- Permissions: a permission the user denied twice (or for good outside the SDK) offers the app's settings; Android 16 body sensors go through Health Connect.
Fixed
- IAB TCF keys:
IABTCF_CmpSdkID/IABTCF_gdprAppliesare written as soon as a TCF configuration resolves, and everyIABTCF_*key is cleared under a Brands configuration.getTcfTcStringreturns no TC string while its encode is pending. - Consent records: a consent read never returns another configuration's record during a configuration switch; the user token and configId are kept per SDK environment; an offline TCF consent whose encode gives up is reported once and retried at the next launch.
- Pinned configuration: a pinned configId decides the flow, like on iOS; offline vendor lists are only reused for the configuration they were fetched for.
- Screens: unsaved choices on the details screens survive a rotation; a double tap submits a decision once; the TCF first-layer cards show without standard-info; the vendor count is bold in every locale.
- Re-initialization:
shutdown()theninitialize()builds a fresh SDK graph, and host events of a shut-down instance are dropped.
Axeptio SDK 1.2.0-beta.1
Added
- sdk: add a host event listener [ENG-13512]
- sdk: report consent sync give-ups and status flow errors to onError
- sample: show the SDK events in an Events panel [ENG-13512]
- consent: report a sync give-up from the repositories' guarded status write
- config: parse askNewConsent, purposes, stacks and expirationTtlDays [ENG-13512]
- consent: re-prompt and consent lifetime like the web CMPs [ENG-13512]
- tcf: list and accept-all the configured purposes and stacks
Changed
- add an emulator testing agent and its test catalog [MSK-264] (#123)
- testing: check EMU-011 for rejected analytics batches
- coverage: exclude generated BuildConfig classes from Kover reports
- add a convention plugin for JVM Compose UI tests
- testing: check EMU-017's disclosure cards after scrolling to them
- document the event listener and callback threads [ENG-13512]
- sdk: spell out that removing the listener can block
- renumber the event emulator tests to EMU-019..021
- analytics: drop the stale claim that host apps implement AnalyticsRepository
- permissions: drop dead card branches and gate PermissionCardKt
- permissions: state plainly what the permanent-denial flag means
- qualify targetService's must-match rule when a configId is pinned
- config: document the defaultConfigId fallback for an unknown pin
- tcf: scope the encode retry kdoc to the GET calls
- sdk: note what the sync give-up watch and the status flow catch can't see
- sdk: drop the TCF re-consent limit that #134 fixed
- sdk: name the status-flow error among events delivered after shutdown
- leave the sample's unit tests out of the public sample
- sample: list the event listener and the Events panel
- sdk: report consent sync give-ups from the repositories' hook only
- sdk: note that a TCF give-up superseded by a Brands configuration reports later
- build: target Android 16 (API 36)
- sample: show a privacy policy for the heart rate permission
- config: describe the per-load onError rule and check it in EMU-009
- consent: describe fixed consent lifetimes and add their emulator tests
- analytics: document the resolved-flow tag, TCF rule and legacy queues
- datastore: say what getRestoreCutoff returns after an app update
- readme: say which TCF purposes the screens list and accept-all consents
- tcf: say why a refreshed configuration may briefly list against the old vendors
- emu: set-permission-flags needs API 33, not 31
- design-system: split the TcfDataCollection vector builder
- design-system: pick the theme without a when on a nullable enum
- design-system: make the primary and secondary buttons non-skippable
- host: move the HostUiState when out of composition [nasdk-6if.14]
- analytics: drop two null checks no configuration can reach
- tcf: say which purposes an accept-all puts under legitimate interest
- readme: describe the catalog-wide accept-all
- configuration: remove the unused api models and consents mapper
- configuration: drop never-null checks from the GVL vendor mapping
- consents: delete the unused SelectionsEncoding
- consents: key the preview fixtures by their purpose ids
- consents: give the vendor details sections one item list
- consents: gate the classes now fully covered
- configuration: drop null checks on values that are never null
- configuration: drop the device-language check getDeviceLanguage already makes
- configuration: build the process-wide ConsentCoordinator under its lock only
- configuration: remove FakeConsentsApi's unused configuration property
- coverage: enforce 98% line and branch coverage per module [ENG-13512]
Fixed
- analytics: keep 408/429 batches and cap batch bodies at 100 KB
- gvl: store the default GVL on disk and stop memoising fallbacks [ENG-13512]
- gvl: store the GVL before memoising it and document the fallbacks
- tcf: write CMP keys on TCF resolution, clear IABTCF keys on Brands
- tcf: write CMP keys on every TCF resolution, supersede TCF on Brands
- tcf: clear IABTCF keys on every resolved Brands configuration
- tcf: restore CMP keys on a same-configuration TCF refetch
- tcf: skip stale IABTCF configuration steps after a flow change
- tcf: supersede the TCF stream only when the Brands clear runs
- tcf: stop a stale flow emission before its bookkeeping
- tcf: drop every TCF-stream command while the resolved flow is Brands
- consents: keep the TCF first-layer cards when standard-info is missing
- sdk: report a Brands retry only once its SYNCED status is stored
- sdk: never call a removed event listener, and log every throwable
- analytics: persist events during a flush and report decision preferences
- analytics: count head evictions and keep the one-argument logEvent
- analytics: copy the preferences a decision passes when it is logged
- analytics: survive foreign cancellations and warn when events are lost
- permissions: stop sending a dismissed permission dialog to settings
- permissions: open settings only after a permanent denial the SDK saw
- permissions: persist permission answers on the SDK scope
- config: let a pinned configId decide the flow, like iOS
- tcf: retry the encode, post consent-only accept, accept any 2xx
- tcf: state the encode retry policy exactly, test a 204 consent post
- tcf: re-evaluate vendor changes after a submission
- sdk: tie a sync give-up to its flow type and stop watching on shutdown
- sdk: drop an SDK instance's host events once shutdown() returns
- sdk: invalidate host events under the lifecycle lock too
- sdk: build every Koin module afresh on each initialize() [nasdk-2nb]
- analytics: share the event queue's lock and drop count per file [nasdk-x4p]
- sdk: keep deprecated module properties for binary compatibility [nasdk-2nb]
- consents: log no vendor toggle for legitimate interests or a no-op master
- consents: submit a consent decision once on a double tap
- consents: keep special-feature-only vendors out of TCF vendor consents
- tcf: stop the Brands geolocation overwriting the stored TCF gdprApplies
- tcf: return no TC string while its encode is pending
- consent: skip a stale Brands snapshot's bookkeeping after a flow flip
- consent: deliver a consent status failure to collectors, not the sharing coroutine
- consent: answer status and reads for this configuration's flow only
- sdk: end the sync give-up watch instead of throwing when the status stream fails
- i18n: resolve Norwegian Bokmål strings on nb devices
- permissions: request READ_HEART_RATE for BodySensors on Android 16
- permissions: keep AndroidPermission and BodySensors' type unchanged
- config: let a slow GVL fetch finish in the background and dedupe it
- config: partition the disk caches by SDK environment
- config: report vendor-list and user-token failures to onError
- network: build the test module's HttpClient without a String bean
- network: send compact JSON request bodies
- network: retry only transport failures and 5xx
- datastore: add stores kept out of Auto Backup, moved there once
- analytics: keep the event queue out of Auto Backup
- datastore: reject opening a file another store moves
- consent: decide the Brands status from one stored record
- sdk: call back reads cancelled by shutdown and report uncaught scope errors
- sdk: answer a leased graph's pending read from that graph, not the new one
- ui: match system-bar icons to SDK screens and pad them for insets
- ui: flip hero status-bar icons when the header leaves the icon line
- ui: let only the incoming screen drive the system bars
- consent: keep the stored user token and configId per SDK environment
- config: publish each configId only together with its vendor list
- consent: keep the repositories' configuration collectors alive after a failure
- consent: retry a TCF consent with the parameters it was encoded with
- consent: keep special-feature-only TCF vendors accepted after a details confirm
- consent: fix each consent's lifetime when it is saved, like the web CMP
- config: apply the cached snapshot first and bookkeep it once on start
- consent: leave a refusal's lifetime to the configuration applied after it
- consent: stamp a lifetime only as owner, retry old records only with a list
- consent: always count the TC string's vendor consents as accepted
- analytics: tag events with the resolved flow, not the declared one
- analytics: report a TCF vendor enabled on consent or legitimate interest
- analytics: move every legacy queue out of backups, drop restored ones
- analytics: read consents again when the configuration changes mid-read
- datastore: treat a legacy file as restored only on a never-updated install
- analytics: read a TCF decision's consents and LI rejections from one record
- analytics: report special-feature-only vendors accepted on a TCF accept-all
- analytics: take a TCF record's LI vendors from the same vendor list
- analytics: re-read a TCF record a vendor list replaced; keep it offline
- network: send geolocation, standard-info, GVL and vendors once, as on iOS
- tcf: list configured purposes only against the vendor list fetched for them
- permissions: offer settings on a card whose request got no answer
- permissions: re-request once before a card offers settings
- permissions: ignore a cancelled permission request in every state
- permissions: report no decision for a cancelled permission request
- emu: rotate through the settings and restore auto-rotate
- emu: report why a device setting or the window dump can't be read
- emu: check that boot really turns da...
Axeptio SDK 1.1.0
Axeptio Native Android SDK 1.1.0
implementation("io.axeptio:sdk:1.1.0")Upgrading from 1.0.1
-
AxeptioPermissionimport. Import it fromio.axeptio.sdk.configuration. The 1.0.1 import from
io.axeptio.foundation.core.configstill compiles but is deprecated. Apps compiled against 1.0.1
keep working without recompiling. After you switch imports, three patterns no longer compile:- assigning a list to
permissionsdirectly; - an empty list with no type argument, such as
withPermissions(emptyList()); - reading
permissionTypeorandroidPermission. UsemanifestPermissionsinstead.
See Upgrading from 1.0.1.
- assigning a list to
-
INTERNET permission. The SDK now declares it, so you can remove the entry you added for it.
-
R8 / ProGuard. The SDK now ships its own rules, so you can remove any
-keeprules you copied
forio.axeptio.**. -
show*()beforeinitialize().showConsentFlow,showConsentManagerand
showPermissionsScreennow throwSdkNotInitializedExceptioninstead of crashing the app.
Fixed
clearConsentData()now removes every stored consent, including theIABTCF_*keys, even when it
is called before the configuration has loaded.- A consent submitted just before, during or right after
clearConsentData()can no longer reappear
after the clear. The same holds across ashutdown()followed byinitialize(). - In the Publisher (TCF) flow, "Accept all" is no longer saved as a refusal when it is pressed before
the vendor list has loaded. The consent screen is shown again instead. - Consent is stored and encoded with the configuration it was given for, even if the configuration
changes while it is being saved. - Calling
shutdown()while a consent screen is open, or during a process restore, no longer crashes
the app. The screen closes cleanly.
Documentation and sample app
- The README now covers setup prerequisites,
consentStatusFlowstates and threading, the TCF
storage keys, the network data collected (for Play Data safety) and migration from the WebView
SDK. - The sample app collects the consent status in a lifecycle-aware way, re-initializes without
restarting, shows the stored consent details, and has a minifiedreleasebuild.
Axeptio SDK 1.1.0-beta.3
Added
- publish: prepare the distribution repo for public release
Changed
- add license, security policy and support contact
- publishing: add name, license, organization and scm to POMs
- readme: add logo banner and badges to match the legacy repo
- readme: title the SDK "Native" to set it apart from the webview SDK
- readme: add alt text to the logo banner
- readme: document setup prerequisites, behaviour and migration from the WebView SDK
- sample: add a README and pin the example to SDK 1.0.1
- readme: import AxeptioPermission from io.axeptio.sdk.configuration
- readme: note permissionType and androidPermission removal when upgrading
- readme: cover untyped listOf() in the 1.0.1 upgrade note
- readme: align the README with 1.1.0 behaviour
- readme: fix NotInitialized advice after shutdown()
- tcf: replace the consent guard with a single-consumer coordinator
Fixed
- sample: collect consent status lifecycle-aware and re-initialize without restarting
- sample: declare core-ktx explicitly instead of relying on activity-compose
- declare the INTERNET permission in the SDK manifest
- api: make AxeptioPermission usable from io.axeptio.sdk.configuration
- api: keep apps compiled against 1.0.1 working without recompiling
- api: give precise migration steps in the withPermissions deprecation
- api: expose manifestPermissions on AxeptioPermission
- build: ship R8 consumer rules in the SDK AAR
- throw SdkNotInitializedException when show* is called before initialize
- close HostActivity on a shutdown() that races an open or opening screen
- resolve HostViewModel eagerly so onCreate never hands a Koin lookup to composition
- keep host screens on a leased Koin graph so shutdown() can never crash them
- make AxContext lease bookkeeping thread-safe and per-lease idempotent
- share one DataStore per file across graphs and use a generation signal for lease staleness
- log why a consent screen closes after shutdown() or re-initialize()
- clearConsentData() always removes the IABTCF keys
- serialize the IABTCF_* clear and clear it before delegating
- drop a stale TCF consent submission's write after a concurrent clear
- make the IABTCF_* clear/write guard process-wide, not per Koin graph
- route every TCF consent/IABTCF write through the generation guard
- tcf: capture generation before launch and read configId under lock
- tcf: gate graph-local clears and retries on active-graph ownership
- tcf: bump generation on graph registration to invalidate stale writes
- tcf: make registerActiveOwner() lock-free to avoid deadlock/ANR risk
- tcf: pack owner and generation into one atomic to close check-then-bump gap
- tcf: bump epoch on a failed clear and stop after a failed PENDING write
- tcf: add per-stream submission tickets to close the overlapping-post gap
- tcf: make Register processing monotonic and fix two other round-12 findings
- tcf: read the configId-changed cleanup's resolvedConfigId at processing time
- tcf: freeze a TCF/Brands submission snapshot so phase 2 never re-reads a newer config
- tcf: carry SdkConfiguration inside the applied snapshot, not a separate configurationFlow read
- tcf: skip a TCF retry rather than encode/submit with an unresolved cmpVersion
- tcf: stop minting a retry ticket before bailing on unresolved configuration
- tcf: attempt both clearAll() clears even if iabTcfStorage's throws
- tcf: never persist a Publisher accept-all built from a null vendor list
Axeptio SDK 1.0.1
First public release of the native Axeptio Android SDK: io.axeptio:sdk:1.0.1.
- Brands and Publisher (IAB TCF) cookie flows, resolved from your remote Axeptio configuration.
- TCF support: the TC string and per-vendor consents (
getTcfTcString,getTcfVendorConsents), plus Brands vendor consents. - Android runtime permission requests from the same configurable flow.
- Consent sync with the Axeptio backend, cached locally and retried on failure.
- Consent state queries and
consentStatusFlow. - Configurable logging (
loggerLevel). - 26 built-in languages.
Requires Android 13 (API 33) or later. See the README for installation and usage.
Axeptio SDK 1.1.0-beta.1
Pre-release of 1.1.0 for early testing (io.axeptio:sdk:1.1.0-beta.1). Not recommended for production; use the latest stable release.
Axeptio SDK 1.0.0
Internal release, published before this repository was public. Not supported: use 1.0.1 or later, whose API differs.