This guide shows how to implement your own custom UI using the IMA SDK for Android. To do so, you need to disable the default UI, set up a new custom UI, and then populate the new UI with ad information obtained from the SDK.
Disable the ad UI
To show a custom UI, first you must disable the default ad UI. To do this, call
AdsRenderingSettings.setDisableUi()
and then pass the AdsRenderingSettings
to
AdsManager.init()
:
MyActivity.java
ImaSdkFactory mSdkFactory = ImaSdkFactory.getInstance(); AdsManager mAdsManager; @Override public void onAdsManagerLoaded(AdsManagerLoadedEvent adsManagerLoadedEvent) { mAdsManager = adsManagerLoadedEvent.getAdsManager(); ... AdsRenderingSettings settings = mSdkFactory.createAdsRenderingSettings(); settings.setDisableUi(true); mAdsManager.init(settings); }
Afterwards, whenever you need to decide whether to show your custom UI, check to see
if there is an ad and call Ad.isUiDisabled()
to check that the default ad UI has
been disabled.
Show custom UI
Once the default UI has been disabled, the next step is to show a custom ad UI.
For this example, add a new RelativeLayout
to your existing video player layout,
then show this layout when an ad is playing and hide it when no ads are playing.
Add the following to the fragment layout file:
fragment_video.xml
<com.google.ads.interactivemedia.v3.samples.samplevideoplayer.SampleVideoPlayer android:id="@+id/sampleVideoPlayer" android:layout_width="match_parent" android:layout_height="match_parent" /> <RelativeLayout android:id="@+id/customUi" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="invisible"> <TextView android:id="@+id/adCounter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:color/holo_green_light" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:text="@string/ad_counter" /> <Button android:id="@+id/learnMoreButton" android:background="@android:color/holo_green_light" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:text="@string/learn_more" android:layout_alignParentRight="true" /> <Button android:id="@+id/skipButton" android:background="@android:color/holo_green_light" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:text="@string/skip_ad" android:enabled="false" android:layout_alignParentRight="true" /> </RelativeLayout>
Then add the code to use the custom UI to the Activity
. To update the UI,
create a timer Handler
and a Runnable
that runs on it.
MyActivity.java
// The view containing the custom UI. private View mCustomUi; // The timer handler. private Handler mTimerHandler = new Handler(); // The Runnable that runs your custom UI update loop. private Runnable mTimerRunnable = new Runnable() { @Override public void run() { updateCustomUi(); mTimerHandler.postDelayed(this, 500); } }; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... mCustomUi = rootView.findViewById(R.id.customUi); mAdCounterUi = (TextView) rootView.findViewById(R.id.adCounter); } @Override public void onAdEvent(AdEvent adEvent) { ... switch (adEvent.getType()) { ... case STARTED: // Start your update loop. mTimerHandler.post(mTimerRunnable); Break; ... case COMPLETED: mCustomUi.setVisibility(View.INVISIBLE); mTimerHandler.removeCallbacks(mTimerRunnable); ... } } @Override public void onPause() { ... // Stop ad UI update loop. mTimerHandler.removeCallbacks(mTimerRunnable); } @Override Public void onResume() { ... // Start ad UI update loop. mTimerHandler.post(mTimerRunnable); }
Ad counter and skip button
Now define the updateCustomUi()
function to populate the UI with ad information.
The details vary by ad format, but you commonly include the ad counter
and a skip button or skip counter if the ad is skippable. Add the following:
MyActivity.java
private void updateCustomUi() { // Runs from the update loop to update the custom UI. Ad ad = mAdsManager.getCurrentAd(); if (ad != null && ad.isUiDisabled()) { // Show the UI. Log.i(LOGTAG, "UI disabled, show custom UI!"); AdPodInfo podInfo = ad.getAdPodInfo(); VideoProgressUpdate update = mAdsManager.getAdProgress(); SimpleDateFormat format = new SimpleDateFormat("mm:ss", Locale.US); // Handle ad counter. String adProgress = format.format( (update.getDuration() - update.getCurrentTime()) * 1000); String adUiString = String.format( Locale.US, "Ad %d of %d (%s)", podInfo.getAdPosition(), podInfo.getTotalAds(), adProgress); mAdCounterUi.setText(adUiString); // Handle skippable ads. if (ad.isSkippable()) { if (update.getCurrentTime() >= ad.getSkipTimeOffset()) { // Allow skipping. mSkipButton.setText(getString(R.string.skip_ad)); mSkipButton.setEnabled(true); } else { String skipString = String.format( Locale.US, "You can skip this ad in %d", (int) (ad.getSkipTimeOffset() - update.getCurrentTime())); mSkipButton.setText(skipString); mSkipButton.setEnabled(false); } mSkipButton.setVisibility(View.VISIBLE); } else { mSkipButton.setVisibility(View.INVISIBLE); } mCustomUi.setVisibility(View.VISIBLE); mCustomUi.bringToFront(); } else { // Hide the UI. mCustomUi.setVisibility(View.INVISIBLE); mTimerHandler.removeCallbacks(mTimerRunnable); } }
In the above code, after checking to see if there is an ad and calling
Ad.isUiDisabled()
to check that the default ad UI has been disabled, call
Ad.getAdPodInfo()
and AdsManager.getAdProgress()
to find the ad's position
in the pod and the ad's progress. For skippable ads, show a skip counter if
you can't yet skip the ad; otherwise, show a skip button. Here's a summary of
common ad information and associated calls:
Information | Call |
---|---|
Current ad in pod | Ad.getAdPodInfo().getAdPosition() |
Total ads in pod | Ad.getPodInfo().getTotalAds() |
Is ad skippable | Ad.isSkippable() |
Seconds until ad can be skipped | Ad.getSkipTimeOffset() - AdsManager.getAdProgress().getCurrentTime() |
Seconds remaining in ad | (AdsManager.getAdProgress().getDuration() - AdsManager.getAdProgress().getCurrentTime()) * 1000 |
Clicking on the Skip Ad button should skip the ad, so set that up in addition to the Learn More button:
MyActivity.java
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... mCustomUi = rootView.findViewById(R.id.customUi); mAdCounterUi = (TextView) rootView.findViewById(R.id.adCounter); // Set up the 'learn more' button handler for the custom UI. mLearnMoreButton = (Button) rootView.findViewById(R.id.learnMoreButton); mLearnMoreButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { // Only works if the UI has been disabled. mAdsManager.clicked(); } }); // Set up the skip button handler for the custom UI. mSkipButton = (Button) rootView.findViewById(R.id.skipButton); mSkipButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { mAdsManager.skip(); } });
The UI must be disabled for AdsManager.clicked()
to work.
Troubleshooting
- Do you have a sample tag that is enabled for disabling ad UI?
- You can copy the URL of this sample tag and paste it into your IMA implementation.
- I can't disable the default UI.
- Check to make sure that you call
AdsRenderingSettings.setDisableUi()
and pass it to theAdsManager
. Check to see thatAd.isUiDisabled()
returnstrue
. In addition, your network must be enabled in Ad Manager to disable an ad UI. If you are enabled, your VAST contains anExtension
that looks like:<Extension type="uiSettings"> <UiHideable>1</UiHideable> </Extension>
If you are still having trouble, check with your account manager to confirm that you are enabled. Some ad types require a specific UI; these ads return with a<UiHideable>
value of 0. If you encounter this, your trafficking team will need to make changes to ensure that these ad types do not serve.