使用 IMA SDK for Android 的自定义界面

本指南介绍了如何使用适用于 Android 的 IMA SDK 实现自己的自定义界面。为此,您需要停用默认界面,设置新的自定义界面,然后使用从 SDK 获取的广告信息填充新界面。

停用广告界面

如需显示自定义界面,您必须先停用默认广告界面。为此,请调用 AdsRenderingSettings.setDisableUi(),然后将 AdsRenderingSettings 传递给 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);
}

之后,每当您需要决定是否显示自定义界面时,请检查是否有广告,并调用 Ad.isUiDisabled() 以检查是否已停用默认广告界面。

显示自定义界面

停用默认界面后,下一步是显示自定义广告界面。在此示例中,请向现有的视频播放器布局添加新的 RelativeLayout,然后在广告播放时显示此布局,并在没有广告播放时隐藏此布局。

将以下代码添加到 fragment 布局文件中:

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>

然后,将用于使用自定义界面的代码添加到 Activity。如需更新界面,请创建一个计时器 Handler 和在其上运行的 Runnable

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);
}

广告计数器和跳过按钮

现在,定义 updateCustomUi() 函数以使用广告信息填充界面。具体细节因广告格式而异,但您通常会添加广告计数器和跳过按钮或跳过计数器(如果广告是可跳过的)。添加以下内容:

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);
    }
}

在前面的代码中,在检查是否有广告并调用 Ad.isUiDisabled() 以检查是否已停用默认广告界面后,调用 Ad.getAdPodInfo()AdsManager.getAdProgress() 以查找广告在连播中的展示位置和广告的进度。对于可跳过的广告,如果用户尚无法跳过广告,请显示跳过计数器;否则,请显示跳过按钮。下面简要介绍了常见的广告信息和相关调用:

信息 致电
广告连播中的当前广告 Ad.getAdPodInfo().getAdPosition()
广告连播中的广告总数 Ad.getPodInfo().getTotalAds()
广告是否可跳过 Ad.isSkippable()
广告可跳过前的秒数 Ad.getSkipTimeOffset() - AdsManager.getAdProgress().getCurrentTime()
广告剩余时长(秒) (AdsManager.getAdProgress().getDuration() - AdsManager.getAdProgress().getCurrentTime()) * 1000

点击跳过广告按钮应会跳过广告,因此除了了解详情按钮之外,还应设置此按钮:

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();
    }
});

必须停用界面,AdsManager.clicked() 才能正常运行。

问题排查

您是否有已启用广告界面停用功能的示例代码?
您可以复制此示例代码的网址,并将其粘贴到您的 IMA 植入中。
我无法停用默认界面。
请检查并确保您调用了 AdsRenderingSettings.setDisableUi() 并将其传递给了 AdsManager。检查 Ad.isUiDisabled() 是否返回 true。此外,您必须在 Ad Manager 中启用您的广告联盟,才能停用广告界面。如果已启用,您的 VAST 将包含如下所示的 Extension
<Extension type="uiSettings">
<UiHideable>1</UiHideable>
</Extension>
如果您仍然遇到问题,请与您的客户经理联系,确认您是否已启用此功能。某些广告类型需要特定的界面;这些广告的 <UiHideable> 值为 0。如果您遇到这种情况,您的广告投放团队需要进行更改,以验证这些广告类型是否未投放。