SDK DocumentationRecipesAnnouncementsSupport Forum
AndroidiOSAnnouncementsSupport Forum

HP4U Integration - Android

HP4U > Android

πŸ’‘

Tip

While reading the documentation, make sure to download and experiment with our Demo App.

Overview

Taboola's HP4U (Homepage For You) solution allows a publisher to display personalized recommendations on the homepage screen, increasing user engagement and boosting CTR (click-through rate).

Once the Taboola team has set up your HP4U configuration, follow the steps below to integrate the solution into your Android app.

🚧

In order to use HP4U, your homepage view must implement RecyclerView. At this time, other layouts are not supported.

πŸ“˜

HP4U is part of Taboola's Mobile SDK, but requires additional, server-side configuration. (This is configured by the Taboola team during your initial onboarding.)

Project dependencies

  1. In your top-level build.gradle file, add the Taboola URL for Artifactory under allprojects > repositories:
buildscript {
    repositories {
        ...
    }
    dependencies {
        ...
    }
}

allprojects {
    repositories {
        ...
        maven {
            // Taboola:
            url 'https://taboolapublic.jfrog.io/artifactory/mobile-release'
        }
    }
}
  1. In your app module build.gradle file, add the Taboola and AndroidX Browser dependencies:
dependencies {

// Always required:
implementation 'com.taboola:<<androidSDKName>>:<<androidSDKVersion>>'
  
// To open the clicked item in a new *tab*:
implementation '<<androidXBrowser>>'

// For projects based on Java 1.7, use this version *instead*: 
// implementation 'androidx.browser:browser:1.0.0'
   
}

Project permissions

  1. Verify that the following permissions are present in AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<!-- (Recommended) Allows Taboola SDK to use the 'IAB OM SDK': -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Initialize Taboola

  1. Create a TBLPublisherInfo object and initialize Taboola:
TBLPublisherInfo publisherInfo = new TBLPublisherInfo("<publisherName>").setApiKey("<apiKey>");
Taboola.init(publisherInfo);
Taboola.init(
    TBLPublisherInfo("<publisherName>").setApiKey("<apiKey>")
)
ParamTypeDescription
publisherNameStringA unique alphabetic String, as provided by Taboola during your initial onboarding. (Your ID might contain dashes, but not spaces.)

Example: "<<publisherID>>".
apiKeyStringA unique string of hexadecimal characters, as provided by Taboola during your initial onboarding. (Taboola will assign you 1 key per application.)

Example: "<<apiKey>>"

🚧

Initialization

  1. Initialization is required once per application. It should be done as early as possible - preferably in a subclass of Application.
  2. Failure to initialize successfully will result in Taboola recommendations not being displayed. Make sure that all paths within your application logic result in a successful initialization.
  1. While testing the integration, add the following debug mode to your to your test build:
// Immediately after Taboola init:
Taboola.enableDebugModes(TBL_DEBUG_MODE.HP_FORCE_SWAP); // For your TEST build only
// Immediately after Taboola init:
Taboola.enableDebugModes(TBL_DEBUG_MODE.HP_FORCE_SWAP) // For your TEST build only

πŸ“˜

Debug mode

To ensure a smooth HP4U integration, Taboola implements a gradual rollout, via A/B Testing.

The above debug mode circumvents A/B testing and allows you to see HP4U take effect.

🚧

Debugging guidelines

  1. Set the debug mode immediately after initializing Taboola.
  2. Remove the debug mode from your production build.

Create a TBLHomePage instance

In the onCreate or onCreateView method (of your Activity or Fragment):

  1. Each TBLHomePage instance uses a specific set of configurations. Use a TBLHomePageSettingsBuilder to create a TBLHomePageSettings instance with the relevant settings:
// In the `onCreate` or `onCreateView` method:

TBLHomePageSettingsBuilder tblHomePageSettingsBuilder = new TBLHomePageSettings.TBLHomePageSettingsBuilder(
                <PageUrl>,
                <sectionNames...>);
// In the `onCreate` or `onCreateView` method:

val tblHomePageSettings: TBLHomePageSettings?  =
    TBLHomePageSettings.TBLHomePageSettingsBuilder(
        <pageUrl>,
        <sectionNames...>).build()
// In the `onCreate` or `onCreateView` method:

val tblHomePageSettings: TBLHomePageSettings?  =
    TBLHomePageSettings.TBLHomePageSettingsBuilder(
        "https://www.example.com/",
        "News",
        "Sports",
        "Entertainment").build()
ParamTypeDescription
pageUrlStringA publicly accessible, canonical URL, with the same content as the home page view - e.g. "https://www.example.com/"

(Taboola crawls this URL for metadata and contextual data.)
sectionNamesString...A complete list of all sections that can potentially display on the homepage - regardless of whether they are fixed or dynamic.

This includes sections not powered by HP4U, as well as sections that are dynamic, or shown only on specific occasions - e.g. holiday specials, breaking news, editorials, etc.

--
The list is passed as a variable number of String arguments (varargs).

Values are case sensitive - e.g. "News", "Sports", etc.

Refer to the example code snippet provided above.
  1. (Optional) Set a fallback image, in case any thumbnail image fails to download:
TBLHomePageSettingsBuilder tblHomePageSettingsBuilder = new TBLHomePageSettings.TBLHomePageSettingsBuilder(
                <PageUrl>,
                <sectionNames...>)
                .setSwappedThumbnailFallbackImage(<swappedThumbnailFallbackImage>); // set fallback image
val tblHomePageSettings: TBLHomePageSettings  =
    TBLHomePageSettings.TBLHomePageSettingsBuilder(
        <pageUrl>,
        <sectionNames...>)
        .setSwappedThumbnailFallbackImage(<swappedThumbnailFallbackImage>) // set fallback image
        .build()
val tblHomePageSettings: TBLHomePageSettings =
    TBLHomePageSettings.TBLHomePageSettingsBuilder(
        "https://www.example.com/",
        "News",
        "Sports",
        "Entertainment")
        .setSwappedThumbnailFallbackImage(R.drawable.default_thumbnail_image) // set fallback image
        .build()
ParamTypeDescription
swappedThumbnailFallbackImageintThe fallback image resource ID

πŸ“˜

If your fallback image also fails (or if you did not provide one), the Taboola SDK will substitute its own fallback image.

  1. Create a TBLHomePage instance to represent your app’s "home page", passing your TBLHomePageSettings instance (from above), and a TBLHomePageListener instance:
TBLHomePage homePage = Taboola.getHomePage(<homePageSettings>, <tblHomePageListener>);
homePage = Taboola.getHomePage(<tblHomePageSettings>, <tblHomePageListener>)
ParamTypeDescription
homePageSettingsTBLHomePageSettingsThe object (instantiated in step 1) that stores your HP4U settings.
tblHomePageListenerTBLHomePageListenerA listener for HP4U events.
See: TBLHomePageListener (below)
  1. Using the TBLHomePageListener instance that you passed above, implement the onHomePageItemClick event:
TBLHomePage homePage = Taboola.getHomePage(
    <homePageSettings>,
    new TBLHomePageListener() {
        @Override
        public boolean onHomePageItemClick(
            String sectionName,
            String itemId,
            String clickUrl,
            boolean isOrganic,
            String customData) {
                // Your click handling code goes here.
                // Return 'false' to ensure that Taboola does not handle the click event.      
            }
    });
homePage = Taboola.getHomePage(
    <homePageSettings>,
    object : TBLHomePageListener() {
        override fun onHomePageItemClick(
            sectionName: String?,
            itemId: String?,
            clickUrl: String?,
            isOrganic: Boolean,
            customData: String?
        ): Boolean {
            // Your click handling code goes here.
            // Return 'false' to ensure that Taboola does not handle the click event.  
        }
    }
)

🚧

Important

By default, Taboola SDK displays content in an external web view. To open organic content directly within your app, you must handle the onHomePageItemClick event.

For more information about event handling, see TBLHomePageListener (below).

Fetch Taboola content

  1. Fetch Taboola content:
homePage.fetchContent();
homePage.fetchContent()
  1. Attach your home page view layout to your TBLHomePage instance:
homePage.attach(<viewGroup>);
homePage.attach(<viewGroup>)
homePage.attach(binding.homepageRecyclerview)
ParamTypeDescription
viewGroupViewGroupYou must pass a RecyclerView. Other layouts are not supported.

Swap out items

🚧

High-level flow

  1. Invoke shouldSwapItemInSection for all items in your home page including those that will not be swapped.
  2. The method should be invoked in the onBindViewHolder method of your RecyclerView adapter.
  3. Pass any needed AdditionalView objects - e.g.authorView - and set any needed properties.
  4. The value returned by shouldSwapItemInSection (true or false) indicates if the item will be swapped.

Now that you have Taboola content, you can swap out the relevant items with personalized ones from Taboola.

For each item on the home page view, invoke the shouldSwapItemInSection method in your TBLHomePage instance.

In the onBindViewHolder method of your RecyclerView.Adapter class:

// Invoke for ALL items in your home page - INCLUDING those that will not be swapped:
boolean swappedPerformed = homePage.shouldSwapItemInSection(
        <linePosition>,
        <sectionName>,
        <lineView>,
        <titleView>,
        <contentView>,
        <thumbnailView>,
        <additionalViews> // Non-mandatory UI components (e.g. `author`) can be passed here
    )
    if (!swappedPerformed) {
    	  // Enables Taboola to track if this item is duplicated elsewhere on the homepage:
    	  homepage.addClickUrlForDuplicationCheck(<itemUrl>);
        
    	  // NOTE:    
    	  // The item will not be swapped. 
    	  // You are responsible for the display of this item.
    }
// Invoke for ALL items in your home page - INCLUDING those that will not be swapped:
val swappedPerformed: Boolean = homePage.shouldSwapItemInSection(
        <linePosition>,
        <sectionName>,
        <lineView>,
        <titleView>,
        <contentView>,
        <thumbnailView>,
        <additionalViews> // Non-mandatory UI components (e.g. `author`) can be passed here
    )
    if (!swappedPerformed) {
    	  // Enables Taboola to track if this item is duplicated elsewhere on the homepage:
    	  homepage.addClickUrlForDuplicationCheck(<itemUrl>)
        
    	  // NOTE:    
    	  // The item will not be swapped. 
    	  // You are responsible for the display of this item.
    }

shouldSwapItemInSection method

🚧

Invoke shouldSwapItemInSection for all items in your home page including those that will not be swapped.

ParamTypeDescription
linePositionintThe row number of the RecyclerView cell.
sectionNameStringThe section name (as configured during the initial onboarding with Taboola).
lineViewViewA UI element that represents the cell.
titleView@Nullable TextView(Optional) The UI component that represents the title for the cell.
contentView@Nullable TextView(Optional) The UI component that represents the description for the cell.
thumbnailView@Nullable ImageView(Optional) The UI component that represents the thumbnail image for the cell.
additionalViewsAdditionalView...(Optional) Used to pass 1 or more additional UI components - e.g. author, article publish time, etc.
See Additional UI components below.

πŸ“˜

Return values

  • true => item will be swapped by Taboola (nothing further required from your side)
  • false => item will not be swapped (you are responsible for the display of this item)

    In this case, make sure to invoke the addClickUrlForDuplicationCheck method.

AdditionalView objects

To swap additional UI components - e.g. author, article publish time - pass 1 or more AdditionalView objects:

boolean swappedPerformed = homePage.shouldSwapItemInSection(
        <linePosition>,
        <sectionName>,
        <lineView>,
        <titleView>,
        <contentView>,
        <thumbnailView>,
        // *Additonal* UI components:
        new AdditionalView.AdditionalViewBuilder(<authorView>, AdditionalView.VIEW_TYPE.AUTHOR).build(),
        new AdditionalView.AdditionalViewBuilder(<timeView>, AdditionalView.VIEW_TYPE.ARTICLE_PUBLISH_TIME).build(),
        new AdditionalView.AdditionalViewBuilder(<subscriptionView>, AdditionalView.VIEW_TYPE.IS_SUBSCRIPTION).presentAfterThumbnail().build(),
        new AdditionalView.AdditionalViewBuilder(<videoView>, AdditionalView.VIEW_TYPE.IS_VIDEO).presentAfterThumbnail().build()
    )
val swappedPerformed = homePage.shouldSwapItemInSection(
        <linePosition>,
        <sectionName>,
        <lineView>,
        <titleView>,
        <contentView>,
        <thumbnailView>,
        // *Additonal* UI components:
        AdditionalViewBuilder(<authorView>, AdditionalView.VIEW_TYPE.AUTHOR).build(),
        AdditionalViewBuilder(<timeView>, AdditionalView.VIEW_TYPE.ARTICLE_PUBLISH_TIME).build(),
        AdditionalViewBuilder(<subscriptionView>, AdditionalView.VIEW_TYPE.IS_SUBSCRIPTION).presentAfterThumbnail().build(),
        AdditionalViewBuilder(<videoView>, AdditionalView.VIEW_TYPE.IS_VIDEO).presentAfterThumbnail().build()
    )

EachAdditionalView object is used to build an additional view, using the following syntax:

new AdditionalView.AdditionalViewBuilder(<yourView>, AdditionalView.VIEW_TYPE.<viewType>).build()

ParamTypeDescription
<yourView>View (or descendant of View)Your View for that UI component.
AdditionalView.VIEW_TYPE.<viewType>AVIEW_TYPE enum value:

AdditionalView.VIEW_TYPE.AUTHOR
AdditionalView.VIEW_TYPE.ARTICLE_PUBLISH_TIME
AdditionalView.VIEW_TYPE.IS_SUBSCRIPTION
AdditionalView.VIEW_TYPE.IS_VIDEO
AdditionalView.VIEW_TYPE.AUTHOR_AVATAR
Defines the property type.

Setting AdditionalView properties

When passing AdditionalView objects, you can optionally set the following properties.

presentAfterThumbnail()

Allows you to delay the rendering of the AdditionalView until the thumbnail image has displayed.

For example, if the thumbnail image is decorated with a video icon, you may want the video icon to display only once the thumbnail is visible.

To do so, invoke presentAfterThumbnail():

new AdditionalView.AdditionalViewBuilder(<videoView>, AdditionalView.VIEW_TYPE.IS_VIDEO).presentAfterThumbnail().build()))

πŸ“˜

Applies to

  • AdditionalView.VIEW_TYPE.IS_SUBSCRIPTION
  • AdditionalView.VIEW_TYPE.IS_VIDEO

makeViewGone()

Allows you to completely remove a given UI component from the view hierarchy of each swapped item.

For example:

You might have an avatar component that is always present in the original item, but not available in the swapped content. If you simply omit that AdditionalView, the UI component will be invisible, but will take up space in the UI.

To remove that UI component completely from the view hierarchy, pass it as an AdditionalView and invoke makeViewGone():

new AdditionalView.AdditionalViewBuilder(<avatarView>, AdditionalView.VIEW_TYPE.AUTHOR_AVATAR).makeViewGone().build()))

markAsRTL()

Requires SDK version 3.9.1 or higher.

Allows explicit control over right-to-left text.

For example, if the AdditionalView contains a mixture of both right-to-left and left-to-right languages, invoke markAsRTL() to enforce a right-to-left flow of text.

new AdditionalView.AdditionalViewBuilder(<authorView>, AdditionalView.VIEW_TYPE.AUTHOR).markAsRTL().build()

addClickUrlForDuplicationCheck method

If the item will not be swapped, the Taboola SDK returns false, and are responsible for the display of the item.

In this scenario, make sure to invoke the addClickUrlForDuplicationCheck method:

// Enables Taboola to track if this item is duplicated elsewhere on the homepage:
homepage.addClickUrlForDuplicationCheck(<itemUrl>);
ParamTypeDescription
itemUrlStringThe fully-qualified, target URL for that item.

πŸ“˜

Swapping items

  1. When you call shouldSwapItemInSection, the Taboola SDK verifies the following:
    1. Is this item a candidate to be swapped?
    2. Did the publisher submit the necessary Views in order to swap this item?
    3. Was Taboola able to fetch a personalized recommendation?
  2. If all checks pass, the Taboola SDK returns true and updates the UI with a personalized recommendation.
  3. If (for any reason) the item will not be swapped, the Taboola SDK returns false. In that case:
    1. You are responsible for the display of this item.
    2. Make sure to invoke the addClickUrlForDuplicationCheck method. This enables Taboola to track if the item is duplicated elsewhere on the homepage.

Refreshing content

If you would like to refresh the Taboola content on the homepage screen - e.g. after a pull-to-refresh gesture, or another trigger - invoke fetchContent again:

homePage.fetchContent();
homePage.fetchContent()

TBLHomePageListener

TBLHomePageListener supports the following events:

public abstract class TBLHomePageListener {

    public void onHomePageStatusChanged(boolean status) {}

    public void onHomePageError(String error, String sectionName) {}

    public boolean onHomePageItemClick(
        String sectionName, 
        String itemId,
        String clickUrl, 
        boolean isOrganic, 
        String customData) {}
  
    public void crossIntegrationFetchAvailable() {}
  
}

πŸ“˜

TBLHomePageListener is an abstract class. You can implement the events that you need, and ignore the others.

Events

onHomePageStatusChanged

When you create your TBLHomePage instance, the onHomePageStatusChanged event is triggered:

@Override
public void onHomePageStatusChanged(boolean status) {}
override fun onHomePageStatusChanged(status: Boolean) {}

πŸ“˜

Callback params

status - has a value of true if your HP4U configuration is set to active.


This is the equivalent of calling homePage.isActive().

onHomePageError

If an error occurs while swapping an item, the onHomePageError event is triggered:

@Override
public void onHomePageError(String error, String sectionName) {}

πŸ“˜

Possible values for error

"SWAP_FAILED_DUE_TO_MISSING_DATA"
"SWAP_FAILED_DUE_TO_MISSING_RECOMMENDATION"
"SWAP_FAILED_DUE_TO_MISSING_START_POSITION_ON_UNIT"
"FAILED_TO_RETRIEVE_RECOMMENDATION"

onHomePageItemClick

By default, Taboola SDK displays content for a clicked item in an external web view.

Use the onHomePageItemClick method to intercept the item click event, and open organic content directly within your app:

@Override
public boolean onHomePageItemClick(
  String sectionName, 
  String itemId,
  String clickUrl, 
  boolean isOrganic, 
  String customData) {
      // Your click handling code goes here.
      // Return 'false' to ensure that Taboola does not handle the click event.  
}

πŸ“˜

Callback params

  • sectionName - The section name (as configured during the initial onboarding with Taboola).
  • itemId - The ID of the clicked item.
  • clickUrl - The Click URL of the clicked item.
  • isOrganic - Indicates if the clicked item is organic

    You can override the click behavior for organic content only.
    That said, at this time, HP4U content is always organic.

  • customData - Extra data passed from Taboola servers. (Can be null.)

πŸ“˜

Return value

  • Return true to indicate that Taboola SDK should open the Click URL.
  • Return false to prevent Taboola SDK from opening the Click URL (allowing you to handle it).

crossIntegrationFetchAvailable

🚧

For special use cases only.

If your homepage screen also includes a Classic Unit (e.g. Taboola Feed), use the crossIntegrationFetchAvailable callback to build Taboola content instances and fetch content:

@Override
public void crossIntegrationFetchAvailable() {
  
 TBLClassicPage classicPage = Taboola.getClassicPage(<pageUrl>, <pageType>);
 TBLClassicUnit classicUnit = classicPage.build(<Context>, <placementName>, <mode>, <placementType>, 
                                                new TBLClassicListener() {});
  classicUnit.fetchContent();
}
override fun crossIntegrationFetchAvailable() {
 val classicPage: TBLClassicPage = Taboola.getClassicPage(<pageUrl>, <pageType>);
 val classicUnit: TBLClassicUnit = classicPage.build(<Context>, <placementName>, <mode>, <placementType>, 
                                                 TBLClassicListener() {});
  classicUnit.fetchContent();
}

Additional methods

This section describes some additional methods provided by TBLHomePage. Implementation of these methods is optional, and is not required for basic integration.

isActive

Returns true if your HP4U configuration is set to active - else, returns false:

homePage.isActive();

πŸ“˜

If the need arises, you can ask the Taboola team to set your HP4U configuration to inactive. In that case, this method will return false.


See also: the onHomePageStatusChanged event (above).

setTBLHomePageListener

If you did not provide a listener when creating your TBLHomePage instance, you can use this method to set one:

homePage.setTBLHomePageListener(TBLHomePageListener tblHomePageListener);

setTargetType

By default, the target type for your TBLHomePage instance is "mix". If Taboola instructs you to use a different target type, use this method:

homePage.setTargetType(String targetType);

setUnifiedId

Use this method to set a unique ID for your HP4U instance:

homePage.setUnifiedId(String unifiedId);

Testing & debugging

For testing purposes, you can enable the following debug mode.

TBL_DEBUG_MODE.HP_FORCE_SWAP

Initially, while you are still testing your integration, the Taboola team configures HP4U so that your homepage swaps items 100% of the time - without any A/B testing.

Once you go live, the Taboola team configures A/B testing. Thereafter, your homepage swaps items for only a given percentage of screen loads.

In order to test and debug, you can force the homepage screen to swap items every time. To do so, add the following line to your test build - just after the init statement:

TBLPublisherInfo publisherInfo = new TBLPublisherInfo("<publisherName>").setApiKey("<apiKey>");
Taboola.init(publisherInfo);

// Immediately after Taboola init:
Taboola.enableDebugModes(TBL_DEBUG_MODE.HP_FORCE_SWAP); // For your TEST build only
Taboola.init(
    TBLPublisherInfo("<publisherName>").setApiKey("<apiKey>")
)

// Immediately after Taboola init:
Taboola.enableDebugModes(TBL_DEBUG_MODE.HP_FORCE_SWAP) // For your TEST build only

❗️

Remember to remove the above debug mode from your production build.

Special use cases

Reordering sections

If your app allows the user to reorder sections, make sure to invoke fetchContent, once the user has applied the changes.

Dynamic resizing of sections

If your app resizes sections dynamically - i.e. the number of items per section is not fixed - make sure to invoke fetchContent each time a section is dynamically resized.

🚧

To ensure that content displays correctly, make sure to invoke notifyDataSetChanged on your RecyclerView.Adapter.

Tips & help

πŸ’‘

  • While reading the documentation, make sure to download and experiment with our Demo App.
  • Stuck? Need a hand? Ask a question in our Support Forum.