Rewarded (or "reward-based") video ads are full screen video ads that users have the option of watching in full in exchange for in-app rewards.

This codelab will walk you through integrating rewarded video ads into an existing Android mobile app, including the design considerations, as well as implementation details, to follow the best practices for rewarded video ads.

What you will build

In this codelab, you're going to integrate rewarded video ads into the sample application called "Impossible Game".

What you'll learn

What you'll need

For this codelab, you will start with the Impossible Game, the game that's impossible to win. A timer begins counting down at the beginning of each round and the game is over when the timer reaches zero. Once the game is over, the user is awarded a coin for playing.

Download the Code

Follow the steps listed below to download all the code for this codelab:

  1. Download the source code from this link.
  2. Unpack the downloaded zip file.

This will unpack a root folder (admob-rewarded-video-master), which contains a directory specific to either Android or iOS. For this codelab you'll navigate to the Android directory. The Android directory contains the start state for this codelab, located in the work directory. The end state for this codelab is located in the final directory. Both work and final directories contain an Android project within a subdirectory named RewardedVideoExample.

You'll do all of your coding in this codelab in Android project located within the work directory. If at any time you're having trouble, you can refer to the Android project located under the final directory.

Open the work project in Android Studio

  1. Open Android Studio and select Import Project.
  2. Navigate to the RewardedVideoExample project under the work directory and select it.
  3. Click OK

You should now have the project open in Android Studio.

The first step to adding the Firebase SDK to your Android project is including a Firebase configuration file within your app. Normally, you would download a google-services.json file from the Firebase console and include it at the app/ directory of your app. For convenience, a sample google-services.json file has already been included in this project.

Next, import the Firebase Ads SDK by adding the following rules to your project-level build.gradle file to include the google-services plugin:

build.gradle -- RewardedVideoExample/

buildscript {
    ...
    dependencies {
        ...
        classpath 'com.google.gms:google-services:3.0.0'
    }
}

You will also add the two lines shown below to your your app-level build.gradle file. Place the compile statement inside the dependencies section and the apply plugin statement at the bottom.

build.gradle -- RewardedVideoExample/app/

  ...
  dependencies {
      ...
      compile 'com.google.firebase:firebase-ads:10.2.4'
  }
  ...

  apply plugin: 'com.google.gms.google-services'
  1. If you see a warning message across the top of the Android Studio window indicating that Gradle needs to perform a sync, click Sync Now. Gradle refreshes your project's libraries to include the dependency you just added.
  2. If you see a message asking you to install the Google Repository, just agree to the install and have Android Studio take care of the download for you. The Google Repository contains code for Gradle to incorporate.
  3. Once your build.gradle files are modified and everything has synced, try rebuilding your project (Run app in the Run menu) to make sure it compiles correctly.

You won't see any changes, but including Firebase and the Mobile Ads SDK is the first step toward getting rewarded video ads into your app.

Before loading ads, your app will need to initialize the Mobile Ads SDK by calling MobileAds.initialize() with your AdMob App ID. This only needs to be done once, ideally at app launch. You can find your app's App ID in the AdMob UI. For this codelab, you will use the test app ID value of ca-app-pub-3940256099942544~3347511713. Following Android best practices, this value should be mapped to the strings resource file located at RewardedVideoExample/app/src/main/res/values/strings.xml of your project. Add an new entry to this file for the AdMob App ID, as shown below.

strings.xml

<resources>
   ...
   <string name="admob_app_id">ca-app-pub-3940256099942544~3347511713</string>
   ...
</resources>

Add the call to initialize(), shown below, to the onCreate() method of the MainActivity class to perform Google Mobile Ads SDK initialization.

MainActivity.java

import com.google.android.gms.ads.MobileAds;
...
public class MainActivity extends Activity {
    private RewardedVideoAd mAd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Initialize the Google Mobile Ads SDK
        MobileAds.initialize(getApplicationContext(),
                getString(R.string.admob_app_id));
        ...
    }

    ...
}

Before going any further, a RewardedVideoAd object is required. The singleton RewardedVideoAd object instance can be retrieved using the MobileAds.getRewardedVideoAdInstance() method. Add a call to this method in the onCreate() method of the MainActivity class and save the reference to a private instance variable.

MainActivity.java

import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.reward.RewardedVideoAd;
...
public class MainActivity extends Activity {
    ...
    private RewardedVideoAd mRewardedVideoAd;
    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MobileAds.initialize(getApplicationContext(),
                getString(R.string.admob_app_id));

        // Get reference to singleton RewardedVideoAd object
        mRewardedVideoAd = MobileAds.getRewardedVideoAdInstance(this);
    }

    ...
}

The RewardedVideoAd object requires notifications of the parent Activity's lifecycle events. To forward these events, call the RewardedVideoAd object's resume(), pause(), and destroy() methods in the parent Activity's onResume(), onPause(), and onDestroy() methods respectively. Update these methods in the MainActivity class as shown below.

MainActivity.java

@Override
public void onResume() {
    mRewardedVideoAd.resume(this);
    super.onResume();
    ...
}

@Override
public void onPause() {
    mRewardedVideoAd.pause(this);
    super.onPause();
    ...
}

@Override
public void onDestroy() {
    mRewardedVideoAd.destroy(this);
    super.onDestroy();
    ...
}

The RewardedVideoAdListener notifies you of rewarded video lifecycle events. You are required to set the listener before loading an ad. The most important event in this listener is onRewarded(), which is called when the user should be rewarded for watching a video.

Add the code shown below, to the MainActivity class, to set a RewardedVideoAdListener on the RewardedVideoAd.

MainActivity.java

...
import android.widget.Toast;
...
import com.google.android.gms.ads.reward.RewardItem;
import com.google.android.gms.ads.reward.RewardedVideoAd;
import com.google.android.gms.ads.reward.RewardedVideoAdListener;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    mRewardedVideoAd.setRewardedVideoAdListener(new RewardedVideoAdListener() {
        @Override
        public void onRewardedVideoAdLoaded() {
            Toast.makeText(getBaseContext(),
                    "Ad loaded.", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onRewardedVideoAdOpened() {
            Toast.makeText(getBaseContext(),
                    "Ad opened.", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onRewardedVideoStarted() {
            Toast.makeText(getBaseContext(),
                    "Ad started.", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onRewardedVideoAdClosed() {
            Toast.makeText(getBaseContext(),
                    "Ad closed.", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onRewarded(RewardItem rewardItem) {
            Toast.makeText(getBaseContext(),
                    "Ad triggered reward.", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onRewardedVideoAdLeftApplication() {
            Toast.makeText(getBaseContext(),
                    "Ad left application.", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onRewardedVideoAdFailedToLoad(int i) {
            Toast.makeText(getBaseContext(),
                    "Ad failed to load.", Toast.LENGTH_SHORT).show();
        }

    });
}

Increment coin count

In the onRewarded()method of the anonymous RewardedVideoAdListener class you just implemented, reward the user for watching the ad by incrementing the coin count by the reward amount.

MainActivity.java

@Override
public void onRewarded(RewardItem rewardItem) {
    // Reward the user for watching the ad.
    Toast.makeText(getBaseContext(), "Ad triggered reward.", Toast.LENGTH_SHORT).show();
    addCoins(rewardItem.getAmount());
}

The next step to monetizing your app with rewarded video ads is making the ad request.

For this codelab, you will make ad requests to the test ad unit value of ca-app-pub-3940256099942544/5224354917. As with previous string literals, this value should be stored in the strings resource file, as shown below.

strings.xml

<resources>
   ...
   <string name="ad_unit_id">ca-app-pub-3940256099942544/5224354917</string>
   ...
</resources>

Ad requests should be made to the singleton RewardedVideoAd instance. It is best practice to call loadAd() as early as possible. Add the code shown below to make this call in the startGame() method, which is invoked at the beginning of every game.

MainActivity.java

import com.google.android.gms.ads.AdRequest;
...
private void startGame() {
    ...
    mGamePaused = false;
    mGameOver = false;


    // Load a reward based video ad 
mRewardedVideoAd.loadAd(getString(R.string.ad_unit_id), new AdRequest.Builder().build());
}

For your app to present the user with the option to watch an ad, you need to modify your main activity's layout file, located at RewardedVideoExample/app/src/main/res/layout/activity_main.xml of your project. Add the XML element shown below to create a Button, which when clicked, will display an ad.

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context=".MainActivity">

   ...

   <!-- Copy this Watch Video Button -->
   <Button
       android:id="@+id/watch_video"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_below="@id/retry_button"
       android:layout_centerHorizontal="true"
       android:onClick="showRewardedVideo"
       android:text="@string/watch_video_button_text" />

   ...
       android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

The android:text attribute on the Button defines the text that is displayed in the button element. Like the AdMob App ID, this value should also be mapped to the strings resource file located at RewardedVideoExample/app/src/main/res/values/strings.xml of your project. Add an new entry to this file for text that clearly presents the user with the option to watch an ad in exchange for a reward.

activity_main.xml

<resources>
   ...
   <string name="watch_video_button_text">Watch Video for additional coins</string>
   ...
</resources>

Set click handler

Setting the android:onClick attribute on the Button element defines the click event handler for a button. A method with the corresponding name, showRewardedVideo() in this case, will be invoked on the Activity hosting the layout. Implement this method in the MainActivity class.

MainActivity.java

public void showRewardedVideo(View view) {
    if (mRewardedVideoAd.isLoaded()) {
        mRewardedVideoAd.show();
    }
}

Within showRewardedVideo(), the show() method is invoked on the singleton RewardedVideoAd object to display the rewarded video ad.

Currently, the button presenting the user with the option to watch a rewarded video ad is always visible. However, we only want this button to be visible at the end of the game. Start by hiding this button at the beginning of every game, as shown below.

MainActivity.java

private Button mShowVideoButton;
...
private void onCreate(Bundle savedInstanceState) {
    ...

    // Get the "show ad" button, which shows a rewarded video when clicked.
    mShowVideoButton = ((Button) findViewById(R.id.watch_video));
    mShowVideoButton.setVisibility(View.INVISIBLE);
}

Now, you'll want to make this button visible at the end of a game if an ad has loaded and is ready to be shown. This can be determined by calling isLoaded() on the RewardedVideoAd object.

MainActivity.java

private void gameOver() {
    ...
    mRetryButton.setVisibility(View.VISIBLE);
    if (mRewardedVideoAd.isLoaded()) {
        mShowVideoButton.setVisibility(View.VISIBLE);
    }
    ...
}

Handle Rotation

The final step is ensuring the watch video is shown following a rotation. In the onResume() method of MainActivity, check if the game is over and an ad is ready to be shown. If both conditions are true, make the show video button visible. These changes are shown below.

MainActivity.java

public void onResume() {
    super.onResume();
    ...
    if(mGameOver && mRewardedVideoAd.isLoaded()) {
        mShowVideoButton.setVisibility(View.VISIBLE);
    }
    mRewardedVideoAd.resume(this);
}

Your app is now ready to display rewarded video ads using the Google Mobile Ads SDK. Run the app and once the countdown timer has expired, you should be presented with the option to watch an ad for additional coins.

What we've covered

Next Steps

Learn More