Integrate Stand-Alone Ads

This guide explains how to integrate stand-alone ads into your app.
You need to install & initialize the SDK based on the Getting Started guide first before you can use stand-alone ads.

Basics

To use stand-alone ads within your app, take the following steps:

  1. Create a layout that can include the ad once it is ready.
  2. Create an Activity or Fragment that handles the ad's request and response.
  3. Request a stand-alone ad.
  4. Include the stand-alone ad view once an ad request returns.
  5. Listen for the completion of the ad playback.
  6. Remove the stand-alone ad view.

Integration

This will take between 60 and 120 minutes depending on your layout's complexity. This guide shows the relevant steps to integrate a simple stand-alone ad. For a more detailed example check the source code of the stand-alone example inside the demo app, which features a sample integration of a stand-alone ad as a pre-roll placement.

Updated Standalone Integration

The standalone ad integration received a breaking code change update in FeedAd version 1.4.3.
If you want to integrate standalone ads and are using an older version of FeedAd you should update the SDK. Do not worry about unresolved class names after the update. Not much has changed. Read through this guide, and you will see how the code has to be refactored.

1. Prepare your Layout

There is only one hard requirement for a stand-alone ad: You need a ViewGroup that the ad can be attached to.

We will use the following layout for this guide:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- the "content" should be shown after the ad, which is why it's visibility is set to gone -->
    <TextView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:gravity="center"
        android:text="placeholder content"
        android:visibility="gone"/>

    <!-- a container that the ad is added to -->
    <FrameLayout
        android:id="@+id/ad_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"/>

    <!-- show a progress bar while the ad is loading -->
    <ProgressBar
        android:id="@+id/progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:indeterminate="true"/>

</FrameLayout>

2. Prepare your Activity

  • Inflate the layout from above and get a reference to the views.
  • Make sure the stand-alone ad is released when the Activity is stopped.
public class MyActivity extends Activity {

    @Nullable private StandaloneAd standaloneAd;
    private TextView content;
    private ProgressBar progressBar;
    private ViewGroup adContainer;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.standalone_example);
        content = findViewById(R.id.content);
        progressBar = findViewById(R.id.progressBar);
        adContainer = findViewById(R.id.ad_container);
    }

    // ... //

    @Override
    protected void onStop() {
        super.onStop();
        // When the activity is stopped while the ad is loading or playing it should be canceled.
        // This does nothing when the ad was already shown.
        if (standaloneAd != null) {
            standaloneAd.cancel();
        }
    }
}

3. Request a Stand-Alone Ad

  • Implement the stand-alone ad listener.
  • Request an ad every time the Activity is started.
public class MyActivity extends Activity {

    // ... //

    @Override
    protected void onStart() {
        super.onStart();

        // check if an ad can be requested
        if (FeedAd.canRequestAd("your-placement-id")) {
            // hide the content and show progress indicator
            content.setVisibility(View.GONE);
            progressBar.setVisibility(View.VISIBLE);
            adContainer.setVisibility(View.GONE);
            adContainer.removeAllViews();

            // request the ad
            standaloneAd = FeedAd.requestStandaloneAd(this, "your-placement-id", new MyStandaloneAdRequestListener());
        } else {
            // show the content
            adContainer.setVisibility(View.GONE);
            progressBar.setVisibility(View.GONE);
            content.setVisibility(View.VISIBLE);
        }
    }

    /**
     * Created when requesting a stand-alone ad
     */
    private class MyStandaloneAdRequestListener implements StandaloneAdRequestListener {

        @Override
        public <T extends View & AdViewConfig> void onAdLoaded(StandaloneAdViewFactory<T> standaloneAdViewFactory) {
            // called with the ad view when the ad is ready to be displayed
        }

        @Override
        public void onError(FeedAdError feedAdError) {
            // called when an error occurs during the request
        }
    }
}

Placement ID?

You can choose placement IDs yourself. A placement ID should be named after the ad position inside your product. For example, if you want to display an ad inside a list of news articles, you could name it "ad-news-overview".
A placement ID may consist of lowercase a-z, 0-9, - and _. You do not have to manually create the placement IDs before using them. Just specify them within the code, and they will appear in the FeedAd admin panel after the first request. Learn more about Placement IDs and how they are grouped to play the same Creative

Prevent unnecessary requests

Although optional, you should always call canRequestAd(placementId) before requesting a stand-alone ad. If this method returns false, there will probably be no ad available. This can save you the time it takes for the ad request to finish.

4. Include the Stand-Alone Ad View

When the ad request returns successfully, you will receive a view inside the onAdLoaded(...) method of your listener. This view should be added to your layout to start the ad. You also need to supply a listener implementation that contains callbacks for the ad playback.

private class MyStandaloneAdRequestListener implements StandaloneAdRequestListener {

    @Override
    public <T extends View & AdViewConfig> void onAdLoaded(StandaloneAdViewFactory<T> standaloneAdViewFactory) {
        // Create the ad view for the current activity
        T adView = standaloneAdViewFactory.createStandaloneAdView(requireActivity(), new StandaloneAdPlaybackListener() {
            @Override
            public void onError(FeedAdError feedAdError) {
                // an error occurred during ad playback
                playContent();
            }

            @Override
            public void onPlacementComplete() {
                // called when the ad playback was completed
            }

            @Override
            public void onSkipped() {
                // called when the ad was skippable and the user clicked the skip button
            }

            @Override
            public void onOpened() {
                // called when the user clicked on the ad
            }
        });
        adContainer.removeAllViews();
        adContainer.addView(view);
        adContainer.setVisibility(View.VISIBLE);
        progressBar.setVisibility(View.GONE);
    }

    // ... //
}

5. Listen for the Completion of the Ad Playback

You can only request one creative for a stand-alone ad. When the playback has finished, the view will remain blank. This is why you should listen for the ad events which signal that the playback has finished and then remove the view from your layout in those callbacks.

There are three different callbacks indicating that the ad is complete. Each one for a different cause of completion.

Successful Callbacks

Callbacks indicating that the Stand-Alone Ad has been played successfully:

  • onPlacementComplete()
    The ad has been played until completion.
  • onSkipped()
    The ad was skippable and the user has clicked the skip button.

Unsuccessful Callbacks

Callbacks indicating that the ad playback was not successful:

  • onError(FeedAdError error):
    The ad request has failed or the playback of the ad has caused an error. An ad request may fail due to connectivity issues or simply because there is no ad available at the moment.

Threading

All listener callbacks are called on the application's main thread.

Execution Sequence

The onError(...) callback might be executed before onAdLoaded() is called in case the ad request fails.
The 'successful callbacks' are always called after onAdLoaded().
For each stand-alone ad request only one completion callback will be called.

public class MyActivity extends Activity {

    // ... //

    /**
     * Shows the content view and hides all progress and ad views.
     */
    private void showContent() {
        adContainer.setVisibility(View.GONE);
        adContainer.removeAllViews();
        progressBar.setVisibility(View.GONE);
        content.setVisibility(View.VISIBLE);
    }

    /**
     * Created when requesting a stand-alone ad
     */
    private class MyStandaloneAdRequestListener implements StandaloneAdRequestListener {

        @Override
        public <T extends View & AdViewConfig> void onAdLoaded(StandaloneAdViewFactory<T> standaloneAdViewFactory) {
            // Create the ad view for the current activity
            T adView = standaloneAdViewFactory.createStandaloneAdView(requireActivity(), new StandaloneAdPlaybackListener() {
                @Override
                public void onError(FeedAdError feedAdError) {
                    // an error occurred during ad playback
                    Log.w("Example", "StandaloneAd failed: " + feedAdError);
                    showContent();
                }

                @Override
                public void onPlacementComplete() {
                    // called when the ad playback was completed
                    Log.d("Example", "onPlacementComplete: the ad played until completion");
                    showContent();
                }

                @Override
                public void onSkipped() {
                    // called when the ad was skippable and the user clicked the skip button
                    Log.d("Example", "onPlacementComplete: the user skipped the ad");
                    showContent();
                }

                @Override
                public void onOpened() {
                    // called when the user clicked on the ad
                }
            });
            adContainer.removeAllViews();
            adContainer.addView(view);
            adContainer.setVisibility(View.VISIBLE);
            progressBar.setVisibility(View.GONE);
        }

        @Override
        public void onError(FeedAdError feedAdError) {
            // called when an error occurs during the request
            Log.w("Example", "StandaloneAd failed: " + feedAdError);
            showContent();
        }
    }
}

Advanced Options

Configure the Ad View

You can change some settings for the stand-alone ad view after it has been created by the factory passed via the onAdLoaded(...) method. The following configuration methods are available:

  • setShutterDrawable(Drawable)
    Sets the background of the ad view while the ad is buffering.
  • setShowLoadingIndicator(boolean)
    Set if the loading indicator should be shown while the ad is loading.

Listen for the Click Out Event

The StandaloneAdPlaybackListener#onOpened() method is called when the user clicks the ad and is redirected to the browser. The stand-alone ad pauses when the user leaves the application and resumes once he returns.

Ad Request Options

You can create an optional request options object, that you can specify alongside the ad request. This object can contain information about the ad's relation to the content of your ad.

You can specify the following options:

Option Description
Content URL A deep-link that opens the screen on which the ad is shown from an external origin.
Placement Context The position of the ad in relation to the main content of the screen. For example, if it is a pre-roll ad shown before the use can access the content.

Example:

AdRequestOptions requestOptions = new AdRequestOptions.Builder()
    .setContentUrl("deeplink//to/your/content")
    .setPlacementContext(PlacementContext.PRE_ROLL)
    .create();

You can pass those options as a second parameter to the standalone ad request:

standaloneAd = FeedAd.requestStandaloneAd(this, "your-placement-id", new MyStandaloneAdRequestListener(), requestOptions);

Full Code Example

The complete code of the stand-alone integration guide.

package com.feedad.demo;

import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.feedad.android.FeedAd;
import com.feedad.android.FeedAdError;
import com.feedad.android.AdViewConfig;
import com.feedad.android.StandaloneAd;
import com.feedad.android.StandaloneAdPlaybackListener;
import com.feedad.android.StandaloneAdRequestListener;
import com.feedad.android.StandaloneAdViewFactory;

public class MyActivity extends Activity {

    @Nullable private StandaloneAd standaloneAd;
    private TextView content;
    private ProgressBar progressBar;
    private ViewGroup adContainer;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.standalone_example);
        content = findViewById(R.id.content);
        progressBar = findViewById(R.id.progressBar);
        adContainer = findViewById(R.id.ad_container);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // When the activity is destroyed while the ad is loading or playing it should be canceled.
        // This does nothing when the ad was already shown.
        if (standaloneAd != null) {
            standaloneAd.cancel();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();

        // check if an ad can be requested
        if (FeedAd.canRequestAd("your-placement-id")) {
            // hide the content and show progress indicator
            content.setVisibility(View.GONE);
            progressBar.setVisibility(View.VISIBLE);
            adContainer.setVisibility(View.GONE);

            // request the ad
            standaloneAd = FeedAd.requestStandaloneAd(this, "your-placement-id", new MyStandaloneAdRequestListener());
        } else {
            showContent();
        }
    }

    /**
     * Shows the content view and hides all progress and ad views.
     */
    private void showContent() {
        adContainer.setVisibility(View.GONE);
        adContainer.removeAllViews();
        progressBar.setVisibility(View.GONE);
        content.setVisibility(View.VISIBLE);
    }

    /**
     * Created when requesting a stand-alone ad
     */
    private class MyStandaloneAdRequestListener implements StandaloneAdRequestListener {

        @Override
        public <T extends View & AdViewConfig> void onAdLoaded(StandaloneAdViewFactory<T> standaloneAdViewFactory) {
            // Create the ad view for the current activity
            T adView = standaloneAdViewFactory.createStandaloneAdView(requireActivity(), new StandaloneAdPlaybackListener() {
                @Override
                public void onError(FeedAdError feedAdError) {
                    // an error occurred during ad playback
                    Log.w("Example", "StandaloneAd failed: " + feedAdError);
                    showContent();
                }

                @Override
                public void onPlacementComplete() {
                    // called when the ad playback was completed
                    Log.d("Example", "onPlacementComplete: the ad played until completion");
                    showContent();
                }

                @Override
                public void onSkipped() {
                    // called when the ad was skippable and the user clicked the skip button
                    Log.d("Example", "onPlacementComplete: the user skipped the ad");
                    showContent();
                }

                @Override
                public void onOpened() {
                    // called when the user clicked on the ad
                }
            });
            adContainer.removeAllViews();
            adContainer.addView(view);
            adContainer.setVisibility(View.VISIBLE);
            progressBar.setVisibility(View.GONE);
        }

        @Override
        public void onError(FeedAdError feedAdError) {
            // called when an error occurs during the request
            Log.w("Example", "StandaloneAd failed: " + feedAdError);
            showContent();
        }
    }
}