Help Center/Details/

New- Android自渲染贴片广告

简介

贴片广告: 贴片广告是一种视频广告形式,开发者可以将广告位设置在其APP内的视频播放前/播放中/播放结束后。贴片广告的时长可以设置成固定时长,如5s/15s等;也可以不限制固定时长,在5-60s范围内由系统返回收益最高的广告,帮助开发者实现收益最大化。贴片广告目前仅支持自渲染,可以使用穿山甲默认播放器,也可以申请使用开发者自己的播放器。

权限

自渲染贴片广告:默认需要申请权限
SDK版本要求: 3400及以上

自渲染贴片请求方法

创建TTAdNative对象

//创建TTAdNative对象,createAdNative(Context context) context需要传入Activity对象
TTAdNative mTTAdNative = TTAdSdk.getAdManager().createAdNative(this);

创建广告请求类型参数AdSlot

AdSlot adSlot = new AdSlot.Builder()
        .setCodeId(codeId)
        .setImageAcceptedSize(640, 320) // 单位px
        .setAdCount(3) //请求广告数量为1到3条
        .build();

参数说明

参数 说明
setCodeId 平台创建的代码位ID 以9开头9位数字
setAdCount 请求数量1-3条,建议设置1
setImageAcceptedSize 设置请求广告的尺寸 单位:px

请求广告

调用 mTTAdNative.loadStream(adSlot, new TTAdNative.FeedAdListener)方法异步加载贴片广告

mTTAdNative.loadStream(adSlot, new TTAdNative.FeedAdListener() {
	//请求广告失败
    @Override
    public void onError(int code, String message) {

      }
    //请求广告成功
    @Override
   public void onFeedAdLoad(List<TTFeedAd> ads) {
                if (ads == null || ads.isEmpty()) {
                    return;
                }
                if (mStreamAdPlayer != null) {
                    mStreamAdPlayer.clear();
                }
                // 使用自定义播放器需要考虑为视频Url预加载
                // 各家开发者的视频播放器个有不同
                // 需要预加载请在通过ttFeedAd.getCustomVideo().getVideoUrl()拿到视频url之后自行预加载
                mStreamAdPlayer = new StreamAdPlayer(ads, mAdLayout);

            }
});

FeedAdListener说明

回调 说明
onError() 请求失败回调
onFeedAdLoad() 请求成功回调

TTFeedAd 接口说明

public interface TTFeedAd {

    /**
     * 获取穿山甲logo,图片大小:80*80
     *
     * @return bitmap对象
     */
    Bitmap getAdLogo();

    /**
     * 广告标题
     *
     * @return
     */
    String getTitle();

    /**
     * 广告描述
     *
     * @return
     */
    String getDescription();

    /**
     * 广告来源
     *
     * @return
     */
    String getSource();

    /**
     * 广告图标Image
     *
     * @return
     */
    TTImage getIcon();

    /**
     * 广告图片Image list
     *
     * @return
     */
    List<TTImage> getImageList();

    /**
     * 得到Feed广告交互类型,贴片广告近为视频广告
     *
     * @return 2:在浏览器打开网页,3:在app中打开,4:下载应用,5:拨打电话 其它:未知类型
     */
    int getInteractionType();

    /**
     * 得到Feed广告图片模式
     *
     * @return 3 大图 2小图 4 组图 5 视频 其它:未知类型
     */
    int getImageMode();

    /**
     * 获取下载状态控制器
     */
    DownloadStatusController getDownloadStatusController();

    /**
     * 注册可点击的View,click/show会在内部完成
     *
     * @param container 渲染广告最外层的ViewGroup
     * @param clickView 可点击的View
     */
    void registerViewForInteraction(@NonNull ViewGroup container, @NonNull View clickView, AdInteractionListener listener);

    /**
     * 注册可点击的View,click/show会在内部完成
     *
     * @param container     渲染广告最外层的ViewGroup
     * @param clickViews    可点击的View的列表
     * @param creativeViews 用于下载或者拨打电话的View
     */
    void registerViewForInteraction(@NonNull ViewGroup container, @NonNull List<View> clickViews, @Nullable List<View> creativeViews, AdInteractionListener listener);

    /**
     * 注册可点击的View,click/show会在内部完成,注册dislike按钮
     *
     * @param container     渲染广告最外层的ViewGroup
     * @param clickViews    可点击的View的列表
     * @param creativeViews 用于下载或者拨打电话的View
     * @param dislikeView   dislike按钮
     * @param listener      点击回调
     */
    void registerViewForInteraction(@NonNull ViewGroup container, @NonNull List<View> clickViews, @Nullable List<View> creativeViews, @Nullable View dislikeView, AdInteractionListener listener);

    /**
     * 设置下载监听器
     */
    void setDownloadListener(TTAppDownloadListener downloadListener);

    /**
     * 兼容下载类广告,使用activity申请权限
     */
    void setActivityForDownloadApp(@NonNull Activity activity);

    /**
     * 获取广告的view,如视频广告的view,在广告平台可设置是否自动播放、是否静音等。
     *
     * @return
     */
    View getAdView();
    
    /**
     * 信息流视频广告回调接口,仅适用于适用穿山甲播放器播放贴片视频广告
     */
    interface VideoAdListener {

        /**
         * 视频广告加载成功
         *
         * @param ad
         */
        void onVideoLoad(TTFeedAd ad);

        /**
         * 视频广告加载失败(原生MediaPlayer内部提供的错误类型)
         * @param errorCode 错误类型:
         *                  MEDIA_ERROR_UNKNOWN
         *                  MEDIA_ERROR_SERVER_DIED
         *
         * @param extraCode 额外错误信息
         *                  MEDIA_ERROR_IO
         *                  MEDIA_ERROR_MALFORMED
         *                  MEDIA_ERROR_UNSUPPORTED
         *                  MEDIA_ERROR_TIMED_OUT
         *                  MEDIA_ERROR_SYSTEM
         *
         */
        void onVideoError(int errorCode, int extraCode);

        /**
         * 视频广告播放回调
         *
         * @param ad
         */
        void onVideoAdStartPlay(TTFeedAd ad);

        /**
         * 视频广告暂停回调
         *
         * @param ad
         */
        void onVideoAdPaused(TTFeedAd ad);

        /**
         * 视频广告续播
         *
         * @param ad
         */
        void onVideoAdContinuePlay(TTFeedAd ad);
    }


    void setVideoAdListener(VideoAdListener videoAdListener);

}

贴片广告行为监听

重要!!! AdInteractionListener涉及到广告计费,必须正确调用 convertView必须使用ViewGroup

在加载到贴片广告后,接入方需要注册在贴片广告中可以点击的View,即TTFeedAd.registerViewForInteraction()方法,以实现广告的功能交互及计。
包含图文点击区域的注册和附加创意按钮点击区域的注册。对于落地页广告,用户点击图文广告区域会跳转到相应的落地页,点击附加创意区域会进行电话拨打、应用下载等操作。

注意: 如果需要点击图文区域也能进行下载或者拨打电话动作,请将图文区域的view传入creativeViewList,详细代码如下

注册点击View示例的示例代码如下,该示例片段在Demo的BaseAdapter getView()方法中调用

/**
  * 注册可点击的View,click/show会在内部完成
  * @param container     渲染广告最外层的ViewGroup
  * @param clickViews    可点击的View的列表
  * @param creativeViews 用于下载或者拨打电话的View
  */
// 可以被点击的view, 也可以把convertView放进来意味整个item可被点击,点击会跳转到落地页
List<View> clickViewList = new ArrayList<View>();
clickViewList.add(convertView);
// 创意点击区域的view 点击根据不同的创意进行下载或拨打电话动作
//如果需要点击图文区域也能进行下载或者拨打电话动作,请将图文区域的view传入creativeViewList
List<View> creativeViewList = new ArrayList<View>();
creativeViewList.add(adViewHolder.mCreativeButton);
// 注册普通点击区域,创意点击区域。重要! 这个涉及到广告计费及交互,必须正确调用。convertView必须使用ViewGroup。
ad.registerViewForInteraction((ViewGroup) convertView, images, clickViewList, creativeViewList,adViewHolder.mDislike,new TTNativeAd.AdInteractionListener() {

    // 点击普通区域的回调
    @Override
    public void onAdClicked(View view, TTNativeAd ad) {

    }

    // 点击创意区域的回调
    @Override
    public void onAdCreativeClick(View view, TTNativeAd ad) {

    }

    // 广告曝光展示的回调
    @Override
    public void onAdShow(TTNativeAd ad) {

    }
});

AdInteractionListener说明

回调 说明
onAdClicked() 点击普通区域回调
onAdCreativeClick() 点击创意区域回调
onAdShow() 广告展示回调

App下载状态控制器

当返回的广告为应用下载类型,即ad.getInteractionType() == TTAdConstant.INTERACTION_TYPE_DOWNLOAD 时,接入方可调用如下示例代码接入 Feed 广告下载控制器:

private void bindDownLoadStatusController(AdViewHolder adViewHolder, final TTFeedAd ad) {
    final DownloadStatusController controller = ad.getDownloadStatusController();
    adViewHolder.mStopButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (controller != null) {
                controller.changeDownloadStatus();
                Toast.makeText(mContext, "改变下载状态", Toast.LENGTH_SHORT).show();
                Log.d(TAG, "改变下载状态");
            }
        }
        });
    adViewHolder.mRemoveButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (controller != null) {
                controller.cancelDownload();
                Toast.makeText(mContext, "取消下载", Toast.LENGTH_SHORT).show();
                Log.d(TAG, "取消下载");
            }
        }
    });
}

广告下载事件监听

//下载监听设置
TTAppDownloadListener downloadListener = new TTAppDownloadListener() {
    //未开始下载
    @Override
    public void onIdle() {

     }
    /**
     * 下载中回调
     * @param totalBytes 安装包总字节数 -1 :未知
     * @param currBytes 当前已下载的字节数
     * @param fileName 下载文件名称
     * @param appName 当前下载的APP名
     */
    @SuppressLint("SetTextI18n")
    @Override
    public void onDownloadActive(long totalBytes, long currBytes, String fileName, String appName) {

    }

     /**
     * 下载暂停回调
     * @param totalBytes 安装包总字节数 -1 :未知
     * @param currBytes 当前已下载的字节数
     * @param fileName 下载文件名称
     * @param appName 当前下载的APP名
     */
    @SuppressLint("SetTextI18n")
    @Override
    public void onDownloadPaused(long totalBytes, long currBytes, String fileName, String appName) {

    }

     /**
     * 下载失败回调
     * @param totalBytes 安装包总字节数 -1 :未知
     * @param currBytes 当前已下载的字节数
     * @param fileName 下载文件名称
     * @param appName 当前下载的APP名
     */
    @Override
    public void onDownloadFailed(long totalBytes, long currBytes, String fileName, String appName) {

    }

     /**
     * 安装完成回调
     * @param fileName 下载文件名称
     * @param appName 当前下载的APP名
     */
    @Override
    public void onDownloadFinished(long totalBytes, String fileName, String appName) {

    }
    /**
     * 下载完成回调
     * @param totalBytes 安装包总字节数 -1 :未知
     * @param fileName 下载文件名称
     * @param appName 当前下载的APP名
     */
    @Override
    public void onInstalled(String fileName, String appName) {

    }

};

TTAppDownloadListener说明

回调 说明
onIdle() 绑定下载监听回调
onDownloadActive() 下载中回调
onDownloadPaused() 下载暂停回调
onDownloadFailed() 下载失败回调
onDownloadFinished() 下载完成回调
onInstalled() 安装完成回调

贴片广告使用自定义播放器

如果App有自己实现的播放器,可以替代sdk中默认的播放器来播放广告,但是需要额外处理好生命周期和事件回调。

创建广告对象封装

class OneAd {
            // 开发者自定义的播放器View
            View adView;
            double duration;
            // 广告对象
            TTFeedAd ttFeedAd;
            public OneAd(View adView, double duration, TTFeedAd ttFeedAd) {
                this.adView = adView;
                this.duration = duration;
                this.ttFeedAd = ttFeedAd;
            }

            public void play() {
                if (adView instanceof VideoView) {
                    ((VideoView)adView).start();
                    if (ttFeedAd.getCustomVideo() != null) {
                        // 使用自定义播放器需要上报视频播放的埋点
                        ttFeedAd.getCustomVideo().reportVideoStart();
                    }
                }
            }

            public void stop() {
                if (adView instanceof VideoView) {
                    if (ttFeedAd.getCustomVideo() != null) {
                        // 使用自定义播放器需要上报视频播放结束的埋点
                        ttFeedAd.getCustomVideo().reportVideoBreak(((VideoView) adView).getCurrentPosition());
                    }
                }
            }

            public void pauseVideo() {
                if (adView instanceof VideoView) {
                    ((VideoView)adView).pause();
                    if (ttFeedAd.getCustomVideo() != null) {
                        // 使用自定义播放器需要上报视频暂停埋点
                        ttFeedAd.getCustomVideo().reportVideoPause(((VideoView) adView).getCurrentPosition());
                    }
                }
            }

            public void continueVideo() {
                if (adView instanceof VideoView) {
                    // Android 自带的VideoView继续播放有关键帧问题
                    // 请使用自己的播放器自行处理继续播放的问题
                    ((VideoView)adView).start();

                    if (ttFeedAd.getCustomVideo() != null) {
                        // 使用自定义播放器需要上报视频继续播放埋点
                        ttFeedAd.getCustomVideo().reportVideoContinue(((VideoView) adView).getCurrentPosition());
                    }
                }
            }
        }

使用自定义播放器

        // StreamAdPlayer 的 getVideoTypeView

        public OneAd getVideoTypeView(final TTFeedAd ttFeedAd) {
            if (ttFeedAd == null || ttFeedAd.getCustomVideo() == null) {
                return null;
            }
            // 这里new出来的是就是自定义的播放器暂时使用android自带的播放器
            // 暂时使用android自带的播放器,开发者此处应该生成自己的播放器
            VideoView videoView = new VideoView(getApplicationContext());
            videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    // 播放器播放结束回调时,应该调用此处进行事件上报
                    if (ttFeedAd.getCustomVideo() != null) {
                        ttFeedAd.getCustomVideo().reportVideoFinish();
                    }
                }
            });
            // 设置Videourl
            videoView.setVideoURI(Uri.parse(ttFeedAd.getCustomVideo().getVideoUrl()));
            // 设置布局等
            ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
            videoView.setLayoutParams(layoutParams);

            ... 

            // 此处返回广告封装对象时,参数里传入播放器实例
            return new OneAd(videoView, ttFeedAd.getVideoDuration(), ttFeedAd);
        }

视频预加载时机

mTTAdNative.loadStream(adSlot, new TTAdNative.FeedAdListener() {
            @Override
            public void onFeedAdLoad(List<TTFeedAd> ads) {

                ...

                // 使用自定义播放器需要考虑为视频Url预加载
                // 需要预加载请在此处通过ttFeedAd.getCustomVideo().getVideoUrl()拿到视频url之后自行预加载

                ...

            }
        });

生命周期控制


    // Activity中

    @Override
    protected void onPause() {
        super.onPause();
        if (mStreamAdPlayer != null) {
            mStreamAdPlayer.onPause();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mStreamAdPlayer != null) {
            mStreamAdPlayer.onResume();
        }
    }

    ...
    // StreamAdPlayer 类中

    public void onPause() {
        // 此处pauseVideo是为了通知自定义播放器暂停
        if (mNowPlayAd != null) {
            mNowPlayAd.pauseVideo();
        }
        mHandler.postDelayedPause();
    }

    public void onResume() {
        // 此处continueVideo是为了自定义播放器续播
        if (mNowPlayAd != null) {
            mNowPlayAd.continueVideo();
        }
        mHandler.postDelayedResume();
    }

CustomizeVideo

方法 说明
getVideoUrl() 获取视频url
reportVideoStart() 上报播放开始
reportVideoPause() 上报播放暂停
reportVideoContinue() 上报播放继续
reportVideoFinish() 上报播放结束
reportVideoBreak() 上报播放中止
reportVideoAutoStart() 上报自动播放
reportVideoStartError() 上报起播错误
reportVideoError() 上报播放中错误

参考Demo

自渲染渲染贴片请参考Demo中StreamActivity
使用自定义播放器可参看Demo中StreamCustomPlayerActivity

自渲染贴片注意点:

1、AdInteractionListener涉及到广告计费,必须正确调用 convertView必须使用ViewGroup

Did the content solve your problem?
Contact us