Introduction
Overview
Integrating with the SDK
Initializing the SDK
Requesting Recommendations
Handling and Displaying Recommendations
Handling Clicks on Recommendations
Using Chrome Custom Tabs
How to Use OBWebView
Widget Viewability
Using the Sample Applications
What’s New in Release 2.1.x
What’s New in Release 2.0.x
Upgrade From 2.0.* Version
Upgrade From 1.5.* Version


Introduction

About This Document

This document describes the Outbrain mobile SDK for the Android platform. It is intended for Android mobile app developers who want to integrate the Outbrain product into their code. The document describes the main Outbrain interface functions.

Software Requirements

The Outbrain SDK is a Java package, and is compatible with API version >= 16. In addition, you will need to use Google Play Services.

Outbrain Application Review

A finalized build must be sent to Outbrain QA at least one week (5 working days) prior to your anticipated release date. We may request changes which will require additional dev resources and could delay your release. We reserve the right to remove our recommendations or restrict the app from generating Outbrain revenue if required changes are not incorporated prior to release. Builds can be submitted via TestFlight or HockeyApp to test-devices@outbrain.com. Your Account Strategist can provide more details.

Recommendation Display Guidelines and Limitations

The recommendations that Outbrain provides are time-sensitive and should be used within one hour of receiving them. Recommendations are intended for specific users at specific times, and any caching or delay in their presentation will have a negative impact on their performance (and the user experience).
The following limitations and guidelines must be applied to the Outbrain recommendations’ display:

  • Storing/caching recommendations with the intent of delaying their presentation on the page is prohibited.
  • Co-mingling of Outbrain recommendations with other content links within the same container is prohibited, unless mutually agreed upon between the client and Outbrain.
  • Altering or replacing an Outbrain recommendation’s text or image is prohibited.
  • All paid recommendations must be uniquely labeled in a manner that can be reasonably associated with the relevant content, as mutually agreed upon between the client and Outbrain.

Overview

The Outbrain Recommendation User Experience

While a user is viewing a page on your mobile app, you can display content recommendations that may be interesting to him or her. You can recommend both related content within your own app, and 3rd-party content recommendations. You can choose how and when to display the recommendations, whether as a footer, in-feed or other format.

The image below illustrates how a user might view Outbrain recommendations:

android-fig1-outbrain-recommendations

Outbrain Recommendations

The Outbrain Workflow

The Outbrain workflow consists of the following main actions:

  • Request content recommendations related to a specific article or app location.
  • Receive a list of recommendations and display them.
  • When a user clicks on a recommendation, navigate to the recommendation.
  • Important: The Outbrain SDK provides the developer an interface for fetching and receiving recommendations in the form of OBRecommendationResponse which encapsulates the json response from the server. Please note that developers should be responsible for implementing the actual UI of the recommendations in their app. Developers are more than welcome to use Outbrain UI examples which can be found in our Sample Apps: Catalog and Journal.

Working with Recommendation Widgets

A widget is a UI component, implemented within the app. When you design your app, you decide which widgets will display Outbrain recommendations and respond to clicks on them.

For each widget displaying Outbrain recommendations, you must consult with your Outbrain account manager and decide on a suitable configuration. The configuration refers to settings such as:

  • The number of recommendations to be displayed in the widget.
  • Whether thumbnail images should be displayed for each recommendation.
  • Whether to recommend articles or videos.

Once these settings are determined, your account manager assigns a unique ID for each different widget configuration. This is the value you pass in the widgetId parameter when calling fetchRecommendations.

For example, the Outbrain Journal sample app uses 4 widgets, each with a unique widget ID:

  • In-stream – the widget appears within homepage or section front content titles.
  • Drawer – a dynamic widget that appears at the bottom of the display when the user scrolls up, which can be expanded to show additional recommendations.
  • Footer – a widget that’s displayed constantly at the bottom of the page.
  • Interstitial – a widget that appears in between article pages.

These widget types are illustrated in the following images:

android-fig3-footer-widget
Footer Widget
android-fig4-inline-widget
In-Stream Widget
android-fig5-minimized-drawer-widget
Minimized Drawer Widget
android-fig6-expanded-drawer-widget
Extended Drawer Widget
android-fig7-interstitial-widget
Interstitial Widget

Integrating with the Outbrain SDK


Updating from an older version of the SDK:

Before continuing to the next steps – please remove OutbrainSDK.jar from the project and all its dependencies.

2 Steps Require to integrate Outbrain SDK with your code:

1) In the project’s build.gradle file (NOT the app module build.gradle) –> under “all projects” –> “repositories” add the following:

allprojects {
    repositories {
        jcenter()
        maven {
            url 'https://dl.bintray.com/outbrainmobile/obsdk'
            credentials {
                username = "OutbrainPublishers"
                password = "*****************"
            }
        }
    }
}
  • Please contact your Account Manager in order to receive a valid password.

See example:


2) In the app module’s build.gradle file –> under “dependencies” –> add the line:

compile 'com.outbrain.obsdk:obsdk:2.1.1'

Initializing the Outbrain SDK

The Outbrain Class

The Outbrain class defines a singleton object that is your main interface with the Outbrain SDK. Your app calls its public static methods in order to interact with the Outbrain server. The Outbrain singleton instance is created automatically; you do not need to create it.

Registering Your App’s Configuration

You will need to register your app’s Outbrain configuration once during the initialization of your app, before calling any other Outbrain method. The register function takes two parameters:
* appContext – your ApplicationContext object.
* appKey – a string that contains the application key you’ve received from your Outbrain account manager.

Here is an example of how to call Outbrain.register:


try {
    Outbrain.register(appContext, appKey);
}
catch (OutbrainException ex)
{
    // handle exception
}

Working in Test Mode

While you are developing your app and debugging the integration with Outbrain, you must configure the SDK to work in test mode. This prevents Outbrain from performing operational actions such as reporting and billing, for clicks that were not made by your app’s users.

Here is an example:


Outbrain.setTestMode(true); // enable test mode when debugging

During the development and testing phase, call setTestMode during your app’s initialization, but remember to remove this call before submitting your app to the app store.

Note:Please use test mode only during development and testing phases. Default value is “false”.

You can also use Outbrain.setTestMode(BuildConfig.DEBUG) for your convenience


Requesting Recommendations

Calling fetchRecommendations

When you want to request content recommendations, call Outbrain.fetchRecommendations. Outbrain will send a response containing a list of recommendations, based on the request parameters and the Outbrain configuration.

fetchRecommendations takes two parameters:
* request – an instance of OBRequest, containing the request details (see OBRequest Properties).
* listener – an instance of RecommendationsListener, which is a response listener that you must implement to handle the request’s success or failure ((See Handling and Displaying Recommendations).

Here is an example of how to call Outbrain.fetchRecommendations:


OBRequest request = new OBRequest(currentUrl, widgetId);

Outbrain.fetchRecommendations(request, new RecommendationsListener() {
    @Override
    public void onOutbrainRecommendationsSuccess(OBRecommendationsResponse recommendations) {
        //Do something with the recommendations (i.e populate UI components)
    }

    @Override
    public void onOutbrainRecommendationsFailure(Exception ex) {
        //Handle failure (write to log, hide the UI component, etc...)
    }
});


Note: Although the fetchRecommendations requests are asynchronous, they are all stored in the same queue, so they are handled in the order in which they were called.

Creating a Recommendation Request

Setting OBRequest Properties

When creating an OBRequest object to provide to fetchRecommendations, set the following properties:

  1. url (mandatory) – the URL of the page for which you’re requesting recommendations. (See Request URL for more details.)
  2. widgetId (mandatory) – the widget ID (see Request Widget ID for more details).
  3. widgetIndex (optional) – the widget index, required if there is more than one widget on the same app page (see Request Widget Index for more details).


Request URL

There are two types of URLs for which you can request recommendations:

  • An article or video page
  • A home page or section front

In the case of a home page or section front, please consult with your Outbrain account manager about how to construct the URL.

Note: Each page’s URL must be unique to the page and consistent (i.e. the same URL must be sent every time recommendations are requested for the same page.)


Request Widget ID

There may be one or more locations in your app where you want to display content recommendations. In addition, you may need to display recommendations in several different widgets on the same page.

Widget IDs are pre-assigned by your account manager, after you define your display requirements for the specific widget. The widget ID maps to settings related to the widget’s display, the number of recommendations returned, etc.

Note: Before using the Outbrain SDK, make sure you have widget IDs assigned to all the widgets in which you’ll need to display recommendations.

For example, the Journal sample app uses 4 different widget IDs:

  • ID “SDK_1” for the in-stream homepage widget.
  • ID “SDK_2” for the interstitial widget.
  • IDs “SDK_3” and “SDK_4” for footer and drawer widgets on article pages.

// create request with mandatory parameters : URL and WidgetID
OBRequest request = new OBRequest();
request.setUrl(post.url);
request.setWidgetId("SDK_1");

In-Stream Widget (ID SDK_1)
In-Stream Widget (ID SDK_1)
Interstitial Widget (ID SDK_2)
Interstitial Widget (ID SDK_2)
Drawer Widget (ID SDK_3)
Drawer Widget (ID SDK_3)
Footer Widget (ID SDK_4)
Footer Widget (ID SDK_4)

Request “Widget Index”

The widget index is a numeric, zero-based value assigned sequentially to all widgets on the same page. If you plan to use (or already using) more than one widget on a single page on your Mobile app – you’ll have to implement the fetching of the recommendations in a specific order according to the guidelines below:

As a side note, it’s important to note that on Mobile apps there is no “real page”, so the meaning of a “page” in this context is a “screen” or a “page” in which 2 widgets or more are shown to the user.

For example, if you have 3 widgets on a page, you’ll assign the indexes 0, 1 and 2 to these widgets. The widget index is used to differentiate between widgets on the same page, so as not to duplicate recommendations sent to different widgets. Widgets on the same page may be of different types (e.g. footer and drawer), or may be multiple instances of the same type (e.g. multiple in-feed), that should display different recommendations.

Guidelines for Fetching Recommendations Multiple Times in a Single Page

Note: This section is relevant only if you plan to have more than one UI Widget on the same screen.
  1. Please make sure that you set the “widget index” variable for each request, i.e. the first request should be sent with idx=0, the second with idx=1 and so on.

  2. The second call for “fetchRecommandations” should be executed from the callback (success or failure) of the first request. The reason we ask our developers to do this is as follows: the response of the first request contains a token from the server that should be sent together with the second request. This is all done “behind the scene” by the SDK, however in order for this to work the SDK has to wait for the response of the first call. Meaning, you, the developer, have to make sure this logic works well within your app.

The code is from Outbrain “Journal” sample app:

    @Override
    public void fragmentBecameVisible() {
        if (! didGetRecommendations) {
            fetchRecommendations(OBDemoWidgetID2);
        }
    }

    private void fetchRecommendations(String widgetId) {
        OBRequest request = new OBRequest();
        request.setUrl(post.url);
        request.setWidgetId(widgetId);
        if (widgetId.equals(OBDemoWidgetID3)) {
            request.setWidgetIndex(1);
        }
        // Default index is 0 so the first request will be according to guidelines. 
        Outbrain.fetchRecommendations(request, this);
    }

    @Override
    public void onOutbrainRecommendationsSuccess(final OBRecommendationsResponse recommendations) {
        String requestWidgetId = recommendations.getRequest().getWidgetJsId();
        didGetRecommendations = true;

        // Response from the first "fetch" call
        if (requestWidgetId.equals(OBDemoWidgetID2)) {
            // First set the result of the first call on the screen, 
            // we can't be sure the second response will be "success".
            setRecommendationsForDrawer(recommendations);
            fetchRecommendations(OBDemoWidgetID3);
        }

        // Response from the second "fetch" call    
        if (requestWidgetId.equals(OBDemoWidgetID3)) {
            setRecommendationsForFooter(recommendations);
        }

    }

    @Override
    public void onOutbrainRecommendationsFailure(Exception ex) {
        Log.e("OB", "failure = " + ex.getMessage());
        ex.printStackTrace();
    }

Please note the following:

  1. The flow starts at fragmentBecameVisible() – there we fetch recommendations for OBDemoWidgetID2.

  2. On the “success” callback we call the second widget OBDemoWidgetID3

  3. In fetchRecommendations() for the second widget (OBDemoWidgetID3) we set idx=1


Handling and Displaying Recommendations

Handling the OBRecommendationsResponse

After your app calls fetchRecommendations, Outbrain calls your recommendations listener’s onOutbrainRecommendationsSuccess method, while providing an OBRecommendationsResponse object. Using this object, you can iterate over the list of recommendations and display them in your app.

Here is an example of an onOutbrainRecommendationsSuccess implementation:


public void onOutbrainRecommendationsSuccess(
                          final OBRecommendationsResponse recResponse)
{
        int numRecs = recResponse.getAll().size();

        for (int i = 0; i < numRecs; i++)
        {
            OBRecommendation rec = recResponse.get(int index);
            // displaying the recommendation

        }
}

Displaying a Recommendation

Each OBRecommendation object contained within the OBRecommendationsResponse has the following properties:

  • content - the recommendation's title.
  • thumbnail – a thumbnail image (OBThumbnail object) related to the recommendation. This property is optional, and is included only if the widget is configured to display images.
  • sourceName – the name of the recommendation's source (publisher). For paid recommendations this is the site name, and for organic recommendations this is the section name.
  • isPaid – indicates whether this a paid or organic recommendation.
  • isVideo – indicates whether the recommendation points to an article containing a video clip.

// Example: displaying a specific recommendation
// getting the recommendation
OBRecommendation rec = recResponse.get(index);
// getting the title
String title = rec.getContent();
// .... populate the relevant UI component with the title

// getting the source
String source = rec.getSourceName();
// .... populate the relevant UI component with the source

// getting image URL
if (rec.getThumbnail() != null) {
   String imageURL = rec.getThumbnail().getUrl();
   // .... populate the relevant UI component with the image
}

// handling paid VS organic recommendation
if (rec.isPaid()) {
   //....Show disclaimer, add paid icon, etc…
}
// handling video VS article
if (rec.isVideo()) {
   //Add video icon on recommendation
}

Recommendation Display Component

Recommendation Display Components

Displaying Thumbnail Images

The thumbnail image is defined by the OBThumbnail object returned within OBRecommendation. It contains the following properties:

  • width – the image width in pixels
  • height – the image height in pixels
  • url – a URL pointing to the image file. Use the URL to render the thumbnail image (see examples in the Outbrain sample apps).

The image width and height values are those agreed upon and determined by the widget ID.

Outbrain Widget Labeling

Any widget displaying Outbrain recommendations must be labeled with a header that is mutually agreed upon between the client and Outbrain.

To comply with Outbrain labeling guidelines:
  1. Add the widget title text agreed upon with Outbrain (e.g. “Promoted stories”).

    Note: For Viewability you'll be using OBTextView for displaying the widget title. Read more about this in widget viewability.
  2. Choose one of the Outbrain logo images from the Outbrain-Resources folder, and add a clickable Outbrain logo to your widget, that opens the following link:
    <a href="http://www.outbrain.com/what-is/default/en-mobile">privacy policy</a>

ios-fig8-labeled-recommendations

Labeled Outbrain Recommendations

See Recommendation Display Guidelines and Limitations for additional instructions about how to display Outbrain recommendations.


Handling Clicks on Recommendations


Navigating to the Recommendation

Note: The best way to understand the new logic is by looking at our Journal Sample App, specifically look at file ViewPagerContainerActivity.java - you will find a good example for the implementation in method:

public void onRecommendationClick(OBRecommendation recommendation)

When a user clicks on a recommendation, navigate to it as follows:


Android-rec-flow


1) Check if it's a paid rec by calling recommendation.isPaid()

For example:

if (recommendation.isPaid()) {
    handlePaidRecommendation(recommendation);
} else {
    // organic
    handleOrganicRecommendation(recommendation);
}

2) Get the URL of the recommendation by:

// rec is an OBRecommendation object returned in OBRecommendationsResponse
String url = Outbrain.getUrl(recommendation);


Note: For paid recommendations, the returned URL is in paid.outbrain.com re-direct format. For organic recommendations the returned URL is in the standard (original) format. Developers should open the url "as is", i.e. without any manipulation such as escaping or decoding.

3) Navigate to the Recommendation


Navigate to Organic Recommendations

Navigate to the organic content using your app’s standard navigation mechanism. You can find an example in the Journal sample app.


Navigate to Paid Recommendations

In order to optimize app performance, when a user clicks on a paid recommendation the SDK will direct the developer to open the recommendation URL in one of the following ways:

1) Using an instance of OBWebView
2) Using Chrome CustomTabs

First, check if the "tapped" recommendation should be opened in CustomTabs (2) or within the app (1) - you do it by calling:


if (recommendation.shouldOpenInCustomTabs()) {
    // Open the URL in CustomTabs
} else {            
    // Open the URL in OBWebView 
}


Using Chrome Custom Tabs

Please follow Android guide for using Chrome Custom Tabs: CustomTabs

For a quick solution you can refer Custom Tabs official Github Repository and just copy the Classes in "shared" directory to your project.

From using custom tabs:

"shared/: Shared code between the Application and demos modules. Feel free to re-use the classes within this directory, which are only provided as a convenience. In particular,CustomTabsHelper can be re-used. This code is not required to use Custom Tabs."

Please Note In using custom tabs Google recommends using warm up to make pages load faster in custom tabs (by pre-loading the page in the background). Unfortunately for Outbrain "paid links" this optimization will result in "fake" click reports on our servers. That's because the paid link is a re-direct link which reports to Outbrain when the user actually opens the recommendation.


Configuring Look & Feel for Custom Tabs

The UI Customizations are done by using the CustomTabsIntent and the CustomTabsIntent.Builder classes. See examples and read more at the official Chrome Custom Tabs developer's page.


Open in OBWebView

When if (rec.shouldOpenInCustomTabs()) is "false" - The URL of the paid recommendation should be open inside OBWebview (developers can use the Class directly or inherit from it for custom appearance / behaviour).

OBWebView - inherits from the base WebView Class with the addition of specific Outbrain business logic. Publishers can set WebViewClient and WebChromeClient on it to receive the corresponding callbacks. However, since this OBWebView is intended for openning paid recommendations, only a close set of methods are supported for the listeners.



Android custom webview


Note: The best way to understand how to implement OBWebView is by looking at our Journal Sample App, specifically look at file PaidRecommendationActivity.java - you will find a good example for the implementation there.

Widget Viewability

Overview

The latest feature of Outbrain Widget Viewability measurement allows Outbrain to optimize the recommendations served for the application audience, hence support a better user experience and app performance.

Widget Viewability measures if the app user has seen the widget on the device screen.

Note: The best way to understand how to implement Viewability is by looking at our Journal Sample App, specifically look at file ArticleFragment.java - you will find a good example for the implementation in method:

setRecommendationsForFooter()


Widget Viewability for Android SDK

Widget Viewability is implemented via OBTextView, which is a child of the native base Class TextView with the addition of reporting Viewability stats to Outbrain back-end.

Android OBTextView

Note: You can either use OBTextView directly or inherit from it for additional customization.



We ask our developers to use OBTextView for the text in the Header of the Outbrain widget. See example below:

journal-sc1


Important Concept - registerOBTextView() method

The most important step in the Widget Viewability implementation (after the view creation of course) is to register the OBTextView with the corresponding widgetID and URL of the page.

public static void registerOBTextView(OBTextView obTextView, String widgetId, String url)

1) Simple Case: You should call registerOBTextView() only once, right after the creation of the view, with the corresponding widgetID and URL of the page.

2) Complex Case: For re-usable views (ViewPager, RecycleView, etc, etc), you have to make sure that every time the re-usable view is updated with new content (i.e. new url) you should call registerOBTextView() method with the new url and the corresponding widgetId.

For Example: A News app which shows articles in a ViewPager and an Outbrain widget is shown at the footer of each article page.

Users can swipe left\right between articles while the app is re-using of the article pages, when the user swipes 5 times to the right, only the content of the page is changing according to the current index in the Pageview, but the views are re-used.

In this case, the developer is responsible to call registerOBTextView whenever a new URL is loaded to the page.


Please Note in case you have more than 1 Outbrain Widget on the same screen, you’ll have to make sure to register each OBTextView with the URL of the screen (same between all widgets) and Widget_ID (different between all widgets).

How to Integrate Widget Viewability Feature?

There are 2 ways to create and use OBTextView (like any other native View on iOS):

  • Via XML Layout File
  • Via Code

XML Layout File

1) Open the layout XML file which contains the Outbrain Widget.

2) Find on the ViewGroup where the Outbrain Widget (including the Header) is implemented.

3) Find the TextView which contains the text in the Header, usually the text is something like “Recommended to You”.

4) Replace the Class of the element from TextView to OBTextView

5) See example:

Screen Shot 2016-08-17 at 2.09.05 PM

Important: In code, register the OBTextView instance and its corresponding widgetID and URL by calling:

Outbrain.registerOBTextView(obTextView, OBFooterWidgetID, post.url);


Implementation via Code

1) Create a new instance of OBTextView by calling:

OBTextView obTextView = new OBTextView(getContext());;

2) Important: call Register() with the OBTextView instance and its corresponding widgetID and url by calling:

Outbrain.registerOBTextView(obTextView, OBFooterWidgetID, post.url);

3) That’s it, from here you’re good to go.


Using the Sample Applications

The Outbrain SDK includes two sample applications that demonstrate how to use the SDK: the Catalog application and the Journal application. Both are located under the Samples folder of your SDK installation. The following sections describe these applications.

The Catalog Sample Application

The Catalog sample application is located under the Samples\Catalog folder of your SDK installation. This application contains a collection of recommendation display layouts, which you can use to get an idea of how to present recommendations in your own app, or even copy the layout code as is.

Catalog first displays a menu of available layouts. Tapping on a layout name displays recommendations in the chosen layout.

ios-fig12-catalog-app-menu
Catalog Application Menu
ios-fig13-catalog-article-image-layout
Catalog Article with Images Layout

The Journal Sample Application

The Journal sample application shows a screen with a list of articles, with Outbrain recommendations interspersed in between the original articles. The user can swipe the recommendations to the left or right, to see additional recommendations.

Journal app tour:
  • Main page, includes in-stream slider recs.
  • Article page, includes footer and drawer.
  • Interstitial page, includes recommendations.

Journal Application

Journal Application

What's New in Release 2.1.x

2.1.1:

  1. Remove Chrome Custom Tabs API level dependency from the SDK code due to API levels stability issues.

  2. Based on #1 above, Remove Class: "CustomTabActivityHelper" from the SDK.

What's New in Release 2.0.x

2.0.4:

Support Android 7.1/API 25 level.
Internal improvement for OBWebVIew class.

2.0.0:

New Features

1) Updated paid recommendation navigation flow for better performance and analytics:

Open Paid Recommendation via Custom WebView (OBWebView) or Chrome CustomTabs, see here

2) Widget Viewability support, see here

3) New URL retrivel method:

public static String getUrl(OBRecommendation rec)

4) Compatible with API version >= 16


Removed (see upgrade instructions)

Init Outbrain With Config File

public static void register(Context applicationContext) throws OutbrainException

Get URL of a Recommendation

public static String getOriginalContentURLAndRegisterClick(OBRecommendation rec);


Stability and performance


Upgrade From 2.0.* Version

1) In case your 2.0.x project is using the Outbrain SDK Class "CustomTabActivityHelper" - your project will not compile after the upgrade and a code update is needed.

Please note that "CustomTabActivityHelper" is a "helper" Class we decided to remove from the SDK due to API level dependencies issues.

In order to perform the needed code update, Please refer to Using Chrome Custom Tabs

2) In case your project is not using the Outbrain SDK Class "CustomTabActivityHelper", no code changes are needed.


Upgrade From 1.5.* Version

1) Make sure to use the following init method:

public static void register(Context applicationContext, String appKey) throws OutbrainException

2) Use

public static String getUrl(OBRecommendation rec)

instead of

public static String getOriginalContentURLAndRegisterClick(OBRecommendation rec);

3) Implement the updated instructions for handling clicks on paid recommendations as described here

4) Implement the new Widget Viewability feature as described here