The Google Mobile Ads SDK also supports custom search styles. If your app already uses the Google Mobile Ads SDK, we recommend you use the AFSMA SDK version instead.
If you're upgrading to version 19.0.0 or later from 18.1.0 or earlier, please see our migration guide.
Prerequisites
This implementation guide assumes you are familiar with the following:
- AdSense Custom Search Ads with custom search styles
- Android app development
Import the AFS Native SDK
Add the SDK
To add the AFS Native SDK to your app, do the following:
Open the build.gradle
file inside your application module directory.
Add a new build rule under dependencies
for the latest version of the SDK:
dependencies {
implementation 'com.google.android.gms:play-services-afs-native:19.1.0'
}
Ensure that your top-level build.gradle
contains a reference to the google()
repo or to maven { url "https://maven.google.com" }
.
Follow these instructions
to include the Google Play Standalone Version Matcher Plugin in your project.
Applying this plugin causes a gradle build error when the AFS Native SDK is
used with an incompatible version of Google Play Services instead of allowing
the app to build but potentially causing runtime crashes. Or, apply the
failOnVersionConflict()
ResolutionStrategy
to your project to cause a build error when incompatible versions of Google Play
Services are used in your project.
Save the changes and click Sync Project with Gradle Files in
the toolbar.
Use AndroidX instead of Android Support Libraries
Starting with version 17.0.0
of the SDK, your app must use Jetpack (AndroidX)
Libraries instead of Android Support Libraries. Compatibility requirements:
- Set
com.android.tools.build:gradle
to v3.2.1 or later. - Set
compileSdkVersion
to 28 or later. - Update your app to use Jetpack (AndroidX); follow the instructions in Migrating to AndroidX.
Classes
To serve AFS native ads in your app, implement the following classes:
- This class is responsible for asynchronously requesting ads, caching and retrieving ads, and rendering ads.
- Each ad context needs a separate
SearchAdController
; for example, if you have a screen which shows ads alongside a list of search results and another screen which shows ads alongside details for a specific product, you should create two separate instances ofSearchAdController
, one for each case. - The constructor needs to be provided your web property code (publisher id),
style ID to apply to
returned ads, and
SearchAdOptions
. TheContext
provided in the constructor must be theActivity
which contains theSearchAdController
and where you will place the adView
. - Call
loadAds
to indicate a new user search and initiate an asynchronous ad request. Any ads loaded from previous calls toloadAds
are cleared from the internal ad cache when a new call is made. - Create a
View
withcreateAdView
to display ad creatives. - Once ads have loaded, call
populateAdView
with aView
previously generated withcreateAdView
to render a cached ad into thatView
. In addition to theView
which is to be populated, provide anadKey
, an arbitrary string to uniquely identify the ad. This associates the specific ad creative returned from the cache with thatadKey
, so when the sameadKey
is passed to a future call topopulateAdView
, the same ad will be returned. For example, ifpopulateAdView
is called for the first time withadKey="keyA"
and renders an ad for hiking boots, each subsequent call topopulateAdView
withadKey="keyA"
will populate the same ad for hiking boots. (Making a new call toloadAds
clears all cached ads and associated ad keys.)
- Pass this object to the
SearchAdController
constructor to customize how ads are requested and displayed. Callbuild()
on aSearchAdOptions.Builder
to create aSearchAdOptions
object.
View
- Create a
View
object to hold ads by callingcreateAdView()
on theSearchAdController
. Displays at most one ad at a time, but the sameView
can be recycled to display different ads over time.
- Call the
loadAds
method on theSearchAdController
with aSearchAdRequest
to initiate an asynchronous ad request. Callbuild()
on aSearchAdRequest.Builder
to create aSearchAdRequest
object.
- Implement this interface and pass it to the
SearchAdController
constructor to register callbacks for several states. - Note:
AdListener
callbacks will not be called on a canceled request (a call toloadAds
that was preempted by another call toloadAds
before the first call resolved).
Example implementation
The example below demonstrates creating a SearchAdController
in a sample
Activity
.
// MainActivity.java implementation
// (MainActivity is a subclass of Activity)
SearchAdController adController;
// adContainer where we will place our ads in this example.
ViewGroup adContainer;
protected void onCreate(Bundle bundle){
super.onCreate(bundle);
adContainer = (ViewGroup) findViewById(...);
// Specify ad options (not required).
SearchAdOptions.Builder adOptionsBuilder = new SearchAdOptions.Builder();
adOptionsBuilder.setAdType(SearchAdOptions.AD_TYPE_TEXT);
adOptionsBuilder.setPrefetch(true);
adOptionsBuilder.setNumAdsRequested(3);
// Provide a callback to trigger when ads are loaded.
AdListener adListener = new AdListener() {
public void onAdLoaded() {
createAndShowAd();
}
};
// Instantiate the SearchAdController.
adController = new SearchAdController(this, "your-client-id", "your-style-id",
adOptionsBuilder.build(), adListener);
}
When the user initiates a query, create a SearchAdRequest
and call loadAds
on the SearchAdController
to start an asynchronous ad request.
// Create the request.
SearchAdRequest.Builder requestBuilder = new SearchAdRequest.Builder();
requestBuilder.setQuery("user query here");
// Load the ads.
adController.loadAds(requestBuilder.build());
Implement your onAdLoaded
callback to populate a loaded ad into an ad view.
private void createAndShowAd() {
// Create a new view that will contain the ad.
View adView = adController.createAdView();
// Attach the new view to the view hierarchy.
adContainer.addView(adView);
// Display the ad inside the adView. We need to provide an adKey to
// indicate which ad is to be displayed in the adView. In this example,
// since we only have one ad, we can provide any constant string. However,
// if you intend to display multiple ads, each ad you wish to display
// should be given a unique adKey of your choosing.
adController.populateAdView(adView, "demoAd");
}
An ad related to the given query will now appear in the adView
.
Investigating errors
The SearchAdController
requires an AdListener
object with the onAdLoaded()
method to notify your app that ads are ready to display. You should also
implement the onAdFailedToLoad()
method so you can detect and correct errors.
For example, you might use the following AdListener
to debug your
implementation:
AdListener adListener = new AdListener() {
public void onAdLoaded() {
// Called when an ad is loaded.
Toast.makeText(MainActivity.this, "Ad Loaded",
Toast.LENGTH_SHORT).show();
Log.d(MainActivity.class.getSimpleName(), "Ad Loaded");
}
public void onAdLeftApplication() {
// Called when an ad leaves the application
// (to go to the browser for example).
Toast.makeText(MainActivity.this, "Ad Left Application",
Toast.LENGTH_SHORT).show();
Log.d(MainActivity.class.getSimpleName(), "Ad Left Application");
}
@Override
public void onAdFailedToLoad(int errorCode) {
// Called when an ad request failed.
Toast.makeText(MainActivity.this, "Ad Failed to Load: " + errorCode,
Toast.LENGTH_SHORT).show();
Log.e(MainActivity.class.getSimpleName(), "Ad Failed to Load: " +
errorCode);
}
};
Constants used in the onAdFailedToLoad()
callback method
are defined in the AdListener.