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.

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 MyStandaloneAdListener());
        } 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 MyStandaloneAdListener implements StandaloneAdListener {

        @Override
        public <T extends View & AdViewConfig> void onAdLoaded(T view) {
            // 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 or playback
        }

        @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
        }
    }
}

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.

private class MyStandaloneAdListener implements StandaloneAdListener {

    @Override
    public <T extends View & AdViewConfig> void onAdLoaded(T view) {
        // called with the ad view when the ad is ready to be displayed
        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 MyStandaloneAdListener implements StandaloneAdListener {

        @Override
        public <T extends View & AdViewConfig> void onAdLoaded(T view) {
            // called with the ad view when the ad is ready to be displayed
            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 or 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
        }
    }
}

Advanced Options

Configure the Ad View

You can change some settings for the stand-alone ad view after it has been 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 StandaloneAdListener#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.


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.StandaloneAdListener;

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 MyStandaloneAdListener());
        } 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 MyStandaloneAdListener implements StandaloneAdListener {

        @Override
        public <T extends View & AdViewConfig> void onAdLoaded(T view) {
            // called with the ad view when the ad is ready to be displayed
            view.setShutterDrawable(new ColorDrawable(Color.BLACK));
            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 or 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
            Log.d("Example", "onOpened: the user clicked the ad");
        }
    }
}