Skip to main content

Introduction


The Osano Consent SDK for Android is a native framework that integrates with the Consent Management Platform on the Osano Website. To use this SDK effectively, you need an Osano account and a published Cookie Consent configuration.

Getting Started

ConsentManager Setup

The ConsentManager is the core object of the SDK. Here's how to create an instance:

import com.osano.mobile_sdk.ConsentManager
import com.osano.mobile_sdk.ui.consent_variant.ConsentDialog
import com.osano.mobile_sdk.ui.consent_categories.StoragePreferenceDialog
import com.osano.mobile_sdk.data.model.Category

val consentResultListener = object : ConsentDialog.OnConsentResultListener {
override fun onAccept(consentedTo: List<Category>) {
print(consentedTo)
}

override fun onDeny() {
print("Rejected all")
}
}

val consentManager = ConsentManager.Builder(this)
.setConfigId("YOUR_CONFIG_ID")
.setCustomerId("YOUR_CUSTOMER_ID")
.setConsentingDomain("YOUR_CONSENTING_DOMAIN")
.build()
note

The configId, customerId, and consentingDomain parameters are mandatory and must match your configuration on the Osano website. The consenting domain should be a fully qualified URL.

Optional Configuration

  • Enable debug logging: .setDebugMode(true)
  • Additional User Information: .setExtUsrData("id")
  • Override country locale: .setCountryCode("us")
  • Override language: .setLanguageCode("es")
  • Enable consent expiration testing mode: .setConsentExpirationTestingMode(10) (debug mode only)
  • Trigger default UI to appear after ConsentManager initialization: .setShouldAutoShowDialog(true)
  • Set the auto-show dialog OnConsentResultListener: .setAutoShowConsentResultListener(consentResultListener)
note

Using extUsrData allows you to associate an external user identifier (such as a user ID from your own system) with the consent record. This parameter is required for cross-device consent, which ensures that a user's consent preferences are recognized consistently across multiple apps, devices, or browser sessions.

For example, if a user logs into your service on both web and mobile, providing the same external ID ensures that their consent preferences are unified and respected across all environments.

Important! It is not advisable to use any personally identifiable information as your extUsrData in order to avoid any privacy violations. Additionally, the provided extUsrData will not be stored in a consent record unless cross-device consent is enabled.

If not explicitly set, the SDK resolves region and language automatically:

Region & jurisdiction

The banner and its regional variant are selected automatically based on the user's location. The region is resolved from the user's IP address at Osano's edge — the consent configuration response carries Osano geolocation headers (x-osano-country, and x-osano-region when applicable) that the SDK reads. No device location permission is requested or required, and the SDK performs no on-device GPS or IP lookup. The resolved value is available via the instance method consentManager.getJurisdiction() (a lowercase country or country-region composite, e.g. us or us-ca).

Language & translations

The banner language follows the device's language setting by default — getDeviceLanguage() first tries an exact language-country match (e.g. en-gb) and falls back to the base language. The SDK ships with 50+ built-in language and locale variants and automatically selects the closest supported match. To force a specific language, call .setLanguageCode("es") on the Builder with any locale returned by ConsentManager.getSupportedLocales() (a BCP 47 tag such as en, pt-br, or zh-hk).

  • List the languages the SDK supports with ConsentManager.getSupportedLocales().
  • Change the language at runtime with consentManager.handleLocaleChange("es").
Variant Override

You can override the consent dialog variant that is displayed to the user. This is useful for testing or forcing a specific banner style regardless of the server-side configuration. Set the variantOverride property on the ConsentManager instance after building it:

val consentManager = ConsentManager.Builder(this)
.setConfigId("YOUR_CONFIG_ID")
.setCustomerId("YOUR_CUSTOMER_ID")
.setConsentingDomain("YOUR_CONSENTING_DOMAIN")
.build()
.apply {
variantOverride = "one" // Supported values: "one", "two", "three", "six"
}
note

When variantOverride is set, it takes priority over the variant determined by the server configuration. Set it to null to revert to the default behavior.

Optional UI Implementation

If you'd rather be in more control of when the UI shows and avoid using .setShouldAutoShowDialog(true), follow these instructions:

  1. ConsentDialog
  2. StoragePreferenceDialog

Both can be displayed in three presentation styles:

  • Dialog showAsDialog()
  • Fragment showAsFragment()
  • Bottom Sheet showAsBottomSheet()

ConsentDialog

val builder = ConsentDialog.Builder(this, consentManager)
.setOnConsentResultListener(object : ConsentDialog.OnConsentResultListener {
override fun onAccept(consentedTo: List<Category>) {
print(consentedTo)
}

override fun onDeny() {
print("Rejected all")
}
})

// Present as dialog
builder.showAsDialog(supportFragmentManager)
note

By default, the ConsentDialog will show in a banner style best suited to the compliance requirements of the user's region.

Depending on the region, the dialog may have an implied consent with automatic timeout. This behavior is expected and can be configured on my.osano.com.

StoragePreferenceDialog

val builder =
StoragePreferenceDialog
.Builder(this@MainActivity, consentManager)
.setOnConsentStoredListener(
object : ConsentManager.OnConsentStoredListener() {
override fun onSuccess(categories: Set<Category>) {
print(categories)
}

override fun onFailure(throwable: Throwable?) {
print("Failed to store consent")
consentManager.clearConsent()
}
},
)

// Present as bottom sheet
builder.showAsDialog(supportFragmentManager)

Customization

Customize the appearance using these optional methods:

builder
.setBackgroundColor(getColor(R.color.white))
.setTextColor(getColor(R.color.black))
.setAccentColor(getColor(R.color.blue))
.setPositiveColor(getColor(R.color.blue))
.setNegativeColor(getColor(R.color.gray))
.setPositiveTextColor(getColor(R.color.white))
.setNegativeTextColor(getColor(R.color.white))
note

The SDK will inherit any text customizations created in the CMP configuration. To update any translations in our supported languages, log into my.osano.com and update the corresponding CMP configuration used by the SDK.

Using Custom UI

If you prefer to use your own UI, you can utilize the ConsentManager APIs directly:

// Store consent
val categories = setOf(Category.Essential, Category.Analytics)
consentManager.storeConsent(categories, object : ConsentManager.OnConsentStoredListener() {
override fun onSuccess(categories: Set<Category>) {}
override fun onFailure(t: Throwable?) {}
})

// Check if user has consented
val hasConsented = consentManager.hasUserConsented()

// Get consented categories
val consentedCategories = consentManager.getConsentedCategories()

// Read the visitor's jurisdiction
val countryCode = consentManager.getCountryCode() // e.g. "US"
val region = consentManager.getRegion() // e.g. "CA" (nullable)
val jurisdiction = consentManager.getJurisdiction() // e.g. "us" or "us-ca"

// Clear stored consent
consentManager.clearConsent()

getJurisdiction() returns the visitor's jurisdiction as a lowercase composite of country and region — either country (e.g. us) or country-region (e.g. us-ca). It is built from the same resolved country as getCountryCode() plus the stored region, and matches the format returned by the web (Osano.cm.jurisdiction) and React Native SDKs.

IAB TCF 2.2

IAB is supported without any additional customization as long as the following conditions are met:

  1. IAB is enabled on the config
  2. The end user is browsing from Canada or a jurisdiction that has adopted GDPR

TCF Strings will be generated and stored in the IABTCF_TCString UserPreferences key, and can be accessed with ConsentManager.getTcfString