Android Consent Library APIs

Usage Notes:

  • Note: Minimum airgap.js version required is 8.37.2. You can upgrade your airgap version in the Admin Dashboard. Don't forget to publish the change!
  • While most of the usage remains consistent with the previous version, the new version introduces enhancements to the initialization of the API and UI instances.
  • This version also includes notable changes such as:
    • Storing Consent Preferences in the Preference Store.
    • Enables Transcend-stored telemetry data.
    • Minor bug fixes and performance improvements.
  • The remaining documentation is organized into three sections:
    • Introduction of Transcend Config to streamline the configuration process.
    • Initialization of the API Instance.
    • Initialization of the UI Instance.
  • Introduced TranscendConfig to streamline the configuration process for both API and UI instances.

    TranscendConfig Properties

    • airgapUrl: The URL of the airgap.js bundle used for consent management. This is a required field.
    • destroyOnClose: A boolean indicating whether the UI view should be destroyed when closed. By default, it is set to true.
    • defaultAttributes: A dictionary containing default attributes to initialize the airgap bundle. This may be useful for overriding parameters such as data-partition. The mobile SDK includes the following defaults:
      • data-cfasync: false
      • data-report-only: on -> note airgap.js is not performing regulation in the mobile app, hence why the script is loaded in report only mode
      • data-partition: <airgap-bundle-id>
      • data-sync: on
      • data-local-sync: off
      • data-backend-sync: on
      • data-telemetry: off
    • token: The user token used to sync consent data in the Preference Store. Refer to the Preference Store for token creation.
    • domainUrls: An array of domain URLs that may be rendered as webViews and require consent synchronization.
    • autoShowUI: A boolean indicating whether to automatically display the UI. By default, it is set to false. When set to true, the UI will be displayed automatically if the user has not provided consent.
    • mobileAppId: The Mobile Application ID is utilized to enable Transcend-stored telemetry data. Native applications can be created within the Admin Dashboard where the Name field should be used as the mobileAppId. Telemetry Information can be accessed on the Admin Dashboard.

    TranscendConfig Usage

    /** Example Usage **/
    String url = "https://transcend-cdn.com/cm/{Bundle_id}airgap.js";
    
    List<String> domainUrls = new ArrayList<>(
      Arrays.asList("https://another-domain.example.com")
    );
    
    /** Add on other airgap data attributes */
    Map<String, String> agAttributes = new HashMap<>();
    
    /* defaultAttributes.put('data-partition','YOUR-PARTITION-ID'); */
    
    TranscendConfig config = new TranscendConfig.ConfigBuilder(url)
      .domainUrls(domainUrls)
      .defaultAttributes(agAttributes)
      .destroyOnClose(false)
      .autoShowUI(false)
      .mobileAppId("your-mobile-app-id")
      .token("user-token")
      .build();
    
    
  • For UI instance initialization, refer to the Initialization of UI Instance.

    TranscendAPI.init() definition

    /**
    * Initializes a API instance of TranscendWebView.
    *
    * @param mContext          The application context.
    * @param config            The TranscendConfig object.
    * @param viewListener      A callback to be notified when the API instance is ready.
    * @return                  The initialized TranscendWebView instance.
    */
    public static TranscendWebView init(
      Context mContext,
      TranscendConfig config,
      TranscendListener.ViewListener viewListener
    )
    

    TranscendAPI.init() usage

    /** Example Usage **/
    String url = "https://transcend-cdn.com/cm/{Bundle_id}airgap.js";
    List<String> domainUrls = new ArrayList<>(Arrays.asList("https://another-domain.example.com"));
    
    /** Add on other airgap data attributes */
    Map<String, String> agAttributes = new HashMap<>();
    /* defaultAttributes.put('data-partition','YOUR-PARTITION-ID'); */
    
    TranscendConfig config = new TranscendConfig.ConfigBuilder(url)
        .domainUrls(domainUrls)
        .defaultAttributes(agAttributes)
        .destroyOnClose(false)
        .autoShowUI(false)
        .mobileAppId("your-mobile-app-id")
        .token("user-token")
        .build();
    
    TranscendAPI.init(
      getApplicationContext(),
      config,
       (success, errorDetails) -> {
        // Code to run when the API instance is ready
        // API's are now accessible
        // UI instance initialization can be done here
        if (success) {
          // Your custom logic goes here
        } else {
          // error handler
        }
      }
    );
    
  • The UI initialization must occur exclusively after both the API instance has been initialized and the onViewReady callback has been invoked.

  • The onCloseListener has been updated to return TrackingConsentDetails along with success and errorDetails. This change allows you to access the consent details immediately after the UI instance is closed without having to call getConsent().

  • After creating the UI instance, you must call loadUrl() to open the consent UI.

    TranscendWebView() constructor

    /**
    * Initializes a UI instance of TranscendWebView.
    *
    * @param mContext          Activity Context object
    * @param config            The TranscendConfig object.
    * @param onCloseListener   The listener to be notified when the UI instance is closed.
    * @return                  The initialized TranscendWebView instance
    */
    public TranscendWebView(
      @NonNull Context context,
      @NonNull TranscendCoreConfig config,
      @Nullable TranscendListener.OnCloseListener onCloseListener
    )
    

    TranscendWebView() usage

    /** Example Usage **/
    String url = "https://transcend-cdn.com/cm/{Bundle_id}airgap.js";
    List<String> domainUrls = new ArrayList<>(Arrays.asList("https://another-domain.example.com"));
    
    /** Add on other airgap data attributes */
    Map<String, String> agAttributes = new HashMap<>();
    /* defaultAttributes.put('data-partition','YOUR-PARTITION-ID'); */
    
    TranscendConfig config = new TranscendConfig.ConfigBuilder(url)
        .domainUrls(domainUrls)
        .defaultAttributes(agAttributes)
        .destroyOnClose(false)
        .autoShowUI(false)
        .mobileAppId("your-mobile-app-id")
        .token("user-token")
        .build();
    
    TranscendWebView transcendWebView = new TranscendWebView(
      (Context) this,
      config,
      (success, errorDetails, trackingConsentDetails) -> {
        // Code to run when the UI instance is closed
        if (success) {
          // success handler
        } else {
          // error handler
        }
      }
    );
    // After initialization, you have to now call loadUrl() for the WebView to load the consent manager
    transcendWebView.loadUrl();
    

Usage Notes:

  • Note: Minimum airgap.js version required is 8.32.0. You can upgrade your airgap version in the Admin Dashboard. Don't forget to publish the change!
  • In order to utilize APIs like getRegimes() and getConsent(), it is essential to invoke TranscendAPI.init() within the `MainActivity`` of your application.
  • Upon completing the initialization in MainActivity, wait for the onViewReady callback to be invoked before you can utilize the APIs or the Transcend UI instance.
  • When moving between Activities, there is no need to reinitialize with init(). Instead, you can directly access the APIs using TranscendAPI.getRegimes() and TranscendAPI.getConsent().
  • The remaining documentation is organized into three sections:
    • Initialization of API Instance.
    • Definitions and usage of APIs.
    • Initialization of UI Instance.
  • To start an API instance in background that is only responsible for calls such as getRegimes() and getConsent(). To show a UI view, refer Initialization of UI Instance.

    TranscendAPI.init() definition

    /**
     * Initializes a API instance of TranscendWebView.
     *
     * @param mContext          The application context.
     * @param mUrl              The URL to load in the WebView.
     * @param viewListener      A callback to be notified when the API instance is ready.
     * @return                  The initialized TranscendWebView instance.
     */
    public static TranscendWebView init(
      Context mContext,
      String mUrl,
      TranscendListener.ViewListener viewListener
    )
    

    TranscendAPI.init() usage

    /** Example Usage **/
    String url = "https://transcend-cdn.com/cm/{Bundle_id}airgap.js";
    TranscendAPI.init(
      getApplicationContext(),
      url,
      (success, errorDetails) -> {
        // Code to run when the API instance is ready
        // API's are now accessible
        if(success){
          TranscendAPI.getRegimes(getApplicationContext(), regimes -> {
            // Your custom logic goes here
            // For example, render UI visible if user regime is GDPR
            if (regimes.contains("GDPR")) {
              // set visibility of Transcend UI instance
            }
          });
        }
        else{
          // error handler
        }
      }
    );
    
    /** Example Usage **/
    TranscendAPI.init(
      applicationContext,
      "https://transcend-cdn.com/cm/{Bundle_Id}/airgap.js",
      // Optional to add syncDomains
      TranscendListener.ViewListener { success, errorDetails ->
        if (success) {
          // success handler
        } else {
          // error handler
        }
      }
    )
    
  • If your mobile application renders a WebView of your websites where Transcend Web Consent is installed, you'll want to ensure that consent state is synced correctly to that WebView. Without this sync, your user may be prompted twice for their consent, once for the native mobile experience, and once for each new domain loaded via a Webview which has Transcend Consent installed. To make this easy, we've extended our init method to allow you to specify additional domains as needed.

    TranscendAPI.init() with syncDomains definition

    /**
     * Initializes a API instance of TranscendWebView
     *
     * @param mContext          The application context.
     * @param mUrl              The URL to load in the WebView.
     * @param syncDomains       A list of domain to which you would like us to sync consent state to.
     *                          NOTE: This creates a webview in the background, this is a
     *                          nice-to-have for customers who render lots of instances of webviews
     *                          for the same domain.
     * @param viewListener      A callback to be notified when the API instance is ready.
     * @return                  The initialized TranscendWebView instance.
     */
    public static TranscendWebView init(
      Context mContext,
      String mUrl,
      List<String> syncDomains,
      TranscendListener.ViewListener viewListener
    )
    

    TranscendAPI.init() with syncDomains usage

    /** Example Usage **/
    import io.transcend.webview.TranscendAPI;
    import io.transcend.webview.TranscendListener;
    
    // Optional list of syncDomains
    String url = "https://transcend-cdn.com/cm/{Bundle_id}airgap.js";
    List<String> syncDomains = new ArrayList<>(Arrays.asList("https://another-domain.example.com"));
    TranscendAPI.init(
      getApplicationContext(),
      url,
      syncDomains,
      (success, errorDetails) -> {
        // Code to run when the API instance is ready
        // API's are now accessible)
        if(success){
          TranscendAPI.getRegimes(getApplicationContext(), regimes -> {
            // Your custom logic goes here
            // For expample, render UI visible if user regime is GDPR
            if (regimes.contains("GDPR")) {
              // set visibility of Transcend UI instance
            }
          });
        }
        else{
          // error handler
        }
      }
    );
    

All listed API calls should be made exclusively after the API instance has been initialized and the onViewReady callback has been invoked.

  • To set up the rules for regime detection based on geoIP or other browser heuristics (language, timezone), please see Consent Experiences.Returns a set of all privacy legal regimes that are detected as applicable to the user. The set will be empty if no regimes are detected.

    TranscendAPI.getRegimes() definition

    /**
     * Fetches the list of regimes using Transcend WebView.
     *
     * @param context  The application context.
     * @param listener A listener to handle the received regimes data.
     * @throws Exception If Transcend.init wasn't called or there was a memory crunch.
     */
    public static void getRegimes(
      Context context,
      TranscendListener.RegimeListener listener
    ) throws Exception
    

    TranscendAPI.getRegimes() usage

    /** Example Usage **/
    import io.transcend.webview.TranscendAPI;
    import io.transcend.webview.TranscendListener;
    
    TranscendAPI.getRegimes(
      getApplicationContext(),
      regimes -> {
        // Your custom logic goes here
        // For example, render UI visible if user regime is GDPR
        if (regimes.contains("GDPR")) {
          // set visibility of Transcend UI instance
        }
      }
    );
    
  • getConsent() returns TrackingConsentDetails. This descriptor has a purposes field which returns an object keyed by all consentable tracking purpose types. The descriptor also has an ISO 8601 timestamp accessible via the timestamp field.

    TranscendAPI.getConsent() definition

    /**
     * Retrieves the consent data using Transcend WebView.
     *
     * @param context  The application context.
     * @param listener A listener to handle the received consent data.
     * @throws Exception If Transcend.init wasn't called or there was a memory crunch.
     */
    public static void getConsent(
      Context context,
      TranscendListener.ConsentListener listener
    ) throws Exception
    

    TranscendAPI.getConsent() usage

    /** Example Usage **/
    import io.transcend.webview.TranscendAPI;
    import io.transcend.webview.TranscendListener;
    
    TranscendAPI.getConsent(
      getApplicationContext(),
      trackingConsentDetails -> {
        // You custom logic goes here
        System.out.println(trackingConsentDetails.getPurposes().get("Analytics"));
    });
    
  • This API allows you to store consent information within the provided WebView Instance's localStorage and updates SharedPreferences. This step can be skipped if you are using the Transcend.Init() method with additional domain syncing or if your application does not utilize a WebView.

  • Details regarding consent can be retrieved using the getConsent() API.

  • The tcString parameter is optional and can be fetched from SharedPreferences using PreferenceManager.getDefaultSharedPreferences(context).getString(IABTranscendSharedPreferences.IAB_TCF_TC_STRING, null).

    TranscendAPI.setConsent() definition

    /**
     * Sets consent information in a WebView's localStorage and updates SharedPreferences.
     *
     * @param mWebView       The WebView instance.
     * @param consentDetails The consent details to be stored.
     * @param tcString       The TCF String (Optional)
     * @param listener       The listener to receive consent status updates.
     */
    public static void setConsent(
      Webview mWebView,
      TrackingConsentDetails consentDetails,
      String tcString,
      TranscendListener.ConsentStatusUpdateListener listener
    ) throws Exception
    

    TranscendAPI.setConsent() usage

    // replace Webview(), TrackingConsentDetails(), "tcString" with actual values
    TranscendAPI.setConsent(
      Webview(),
      TrackingConsentDetails(),
      "tcString",
      (TranscendListener.ConsentStatusUpdateListener) (success, errorDetails) -> {
        if (success) {
          // success handler
        } else {
          // error handler
        }
      }
    );
    
  • Please review this doc on configuring the associated tracking purposes for your SDKs.

  • Determines whether a given SDK is allowed to load based on serviceId. The serviceId is the unique slug associated with each SDK. The callback will return a ConsentStatus enum value.

    TranscendAPI.getSDKConsentStatus() definition

    // The possible consent statuses for a given SDK
    public enum ConsentStatus {
        ALLOW,
        BLOCK,
        TCF_ALLOW,
        NO_SDK_FOUND,
        INTERNAL_ERROR
    }
    
    /**
     * Retrieves the SDK consent status, either from the cached data or by fetching fresh data from the backend API.
     *
     * @param context   The application context.
     * @param serviceId The service ID.
     * @param listener  The ConsentStatusListener callback.
     * @throws Exception If Transcend.init wasn't called or there was a memory crunch.
     */
    public static void getSdkConsentStatus(
      Context context,
      TranscendListener.ConsentStatusListener listener
    ) throws Exception
    

    TranscendAPI.getSDKConsentStatus() usage

    /** Example usage **/
    import io.transcend.webview.TranscendAPI;
    import io.transcend.webview.TranscendListener;
    
    TranscendAPI.getSdkConsentStatus(
      getApplicationContext(),
      "datadog-java-sdk",
      consentStatus -> {
      if (consentStatus == ConsentStatus.ALLOW || consentStatus == ConsentStatus.TCF_ALLOW) {
        // load the SDK
      }
    });
    
  • For senarios where destoryOnClose is set to false, the showConsentManager method can be reused show the consent manager UI. The viewState parameter is optional and can be used to show a specific view state in the consent manager. If the viewState parameter is not provided, the default view state for the user's regime will be shown.

  • Information about different types of view states can be found here

  • Note: This method is only applicable for Android XML Layout based implementations where TranscendWebView is initilaized as shown in the Initialization of UI Instance.

    TranscendWebView.showConsentManager() definition

    /**
     * Shows the consent manager UI.
     *
     * @param viewState The view state to show in the consent manager.
     * @throws Exception If Transcend.init wasn't called or there was a memory crunch.
     */
    public static void showConsentManager(@Nullable String viewState) throws Exception
    

    TranscendWebView.showConsentManager() usage

    import io.transcend.webview.TranscendWebView;
    /** Example Usage **/
    TranscendWebView transcendWebView = findViewById(R.id.transcendWebView);
    // Show the default view state for the user's regime
    transcendWebView.showConsentManager(null);
    // Show a specific view state
    transcendWebView.showConsentManager("CompleteOptions");
    
  • For scenarios where destoryOnClose is set to false, the hideConsentManager method can be used to hide the consent manager UI view.

  • Note: This method is only applicable for Android XML Layout based implementations.

    TranscendWebView.hideConsentManager() definition

    public static void hideConsentManager() throws Exception
    

    TranscendWebView.hideConsentManager() usage

    /** Example usage **/
    import io.transcend.webview.TranscendWebView;
    
    TranscendWebView.hideConsentManager();
    

The UI initialization must occur exclusively after both the API instance has been initialized and the onViewReady callback has been invoked.

/**
 * Initializes a UI instance of TranscendWebView.
 *
 * @param mContext          Activity Context object
 * @param mUrl              The URL to load in the WebView.
 * @param onCloseListener   The listener to be notified when the UI instance is closed.
 * @return                  The initialized TranscendWebView instance.
 */
public TranscendWebView(
  @NonNull Context context,
  String transcendConsentUrl,
  TranscendListener.OnCloseListener onCloseListener
)
<io.transcend.webview.TranscendWebView
  android:id="@+id/transcendWebView"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  app:destroyOnClose="false"
  app:transcendConsentUrl= "@string/transcendConsentUrl" />
TranscendWebView transcendWebView = findViewById(R.id.transcendWebView);
transcendWebView.setOnCloseListener((success, errorDetails) -> {
    // Code to run when the UI instance is closed
    if(success){
        // success handler
    }
    else{
        // error handler
    }
  }
);
TranscendWebView transcendWebView = new TranscendWebView(
  (Context) this,
  "https://transcend-cdn.com/cm/{Bundle_id}airgap.js",
  (TranscendListener.OnCloseListener) (success, errorDetails) -> {
    // Code to run when the UI instance is closed
    if (success) {
      // success handler
    } else {
      // error handler
    }
  }
);

@Composable
fun TrComposable(applicationContext: Context) {
    // Initialize TranscendWebView
    AndroidView(factory = { context ->
        // Always use TranscendWebView for UI purpose
        TranscendWebView(context, "https://transcend-cdn.com/cm/{Bundle_Id}/airgap.js", TranscendListener.OnCloseListener { success, errorDetails ->
            if (success) {} else {}
        })
    })
}