原生广告
原生广告
概述
原生广告是一种与应用内容和设计自然融合的广告形式,开发者只需按照标准集成步骤即可在应用中无缝展示广告内容。原生广告能够与应用的界面和用户体验协调一致,不会干扰用户的正常使用。用户可以在浏览应用内容时自然地接触到这些广告,从而提高广告的接受度和互动性。开发者可以根据应用的风格和用户的需求定制广告的展示方式,以实现最佳的广告效果和用户体验。
模板渲染
优推SDK提供多种的广告模板样式,上下图文、左右图文、三小图等
模板渲染场景常见于应用的内容信息流中与应用内容穿插展示,如资讯列表页每隔几条资讯穿插一条广告。
广告加载和展示
使用SAAllianceAdSdk.getSAAllianceAdManager().createSAAllianceAd()
获取 SAAllianceAd 接口类型对象;
调用loadSAExpressFeedAd(SAAllianceAdParams params, ViewGroup containers, SAExpressFeedAdLoadListener listener)
进行广告加载;
调用render()
方法进行后,在onRenderSuccess(View view)
回调中获取广告视图 View 进行展示。
SAAllianceAd原生模版渲染广告相关方法说明
方法 | 说明 |
---|---|
加载原生模版渲染广告 |
SAExpressFeedAdLoadListener说明
方法 | 说明 |
---|---|
加载成功, | |
加载失败,code 错误码,message 错误信息 | |
广告素材加载成功 | |
void onTimeOut() | 加载超时 |
SAExpressFeedAd说明
加载获取到的原生模版渲染广告实例,用于获取广告视图、生命周期监听,获取价格等
方法 | 说明 |
---|---|
渲染广告视图 | |
设置生命周期监听,在调用 | |
设置视频播放状态监听 | |
获取广告价格,单位:分 | |
销毁广告 |
loadSAExpressFeedAd方法说明
参数 | 说明 | 是否必填 |
---|---|---|
广告参数 | 必填 | |
广告加载结果回调 | 必填 |
SAAllianceAdParams说明
必填,且必须大于0 | ||
SAExpressFeedAdInteractionListener广告生命周期回调
方法 | 说明 |
---|---|
原生模版渲染广告点击 | |
void onAdShow() | 原生模版渲染广告展示 |
void () | 原生模版渲染广告关闭 |
void | 模版渲染失败,code 错误码,msg 错误信息 |
模版渲染成功,view 广告视图 |
SAExpressFeedAdVideoListener广告视频状态回调
方法 | 说明 |
---|---|
视频播放失败, 错误码, 错误信息 | |
void onVideoLoad(); | 视频加载完成 |
void onVideoStartPlay(); | 视频开始播放 |
void onVideoPause(); | 视频暂停 |
视频播放完毕 |
请求模板渲染广告示例
原生广告通过setImageAcceptedWidth,setImageAcceptedHeight设置宽高,单位为dp,设置宽度不能小于或等于0,否则会填充失败。
private void loadExpressFeedAd(Activity context, String posId, int width, int height, ViewGroup viewGroup) {
//设置广告参数
SAAllianceAdParams params = new SAAllianceAdParams();
params.setPosId(sposId); //设置广告位ID
params.setMute(true); //设置视频素材是否默认静音,默认为true
//宽度必穿,且需大于0,单位dp;广告宽度将根据所传宽度进行展示
params.setImageAcceptedWidth(width);
params.setImageAcceptedHeight(height);//高度可传0,将根据广告模版类型自适应
//广告对象初始化
SAAllianceAd saAllianceAd = SAAllianceAdSdk.getSAAllianceAdManager().createSAAllianceAd(context);
saAllianceAd.loadSAExpressFeedAd(params, null, new SAExpressFeedAdLoadListener() {
@Override
public void onExpressFeedAdLoad(List<SAExpressFeedAd> saExpressFeedAdList) {
if (saExpressFeedAdList == null || saExpressFeedAdList.isEmpty()) {
Log.e(TAG, "广告加载失败");
return;
}
for (SAExpressFeedAd saExpressFeedAd : saExpressFeedAdList) {
String ecpm = saExpressFeedAd.getECPM(); //获取广告价格,单位分
//设置广告交互监听
saExpressFeedAd.setExpressFeedAdInteractionListener(new SAExpressFeedAdInteractionListener() {
@Override
public void onAdClick() {
Log.i(TAG, "广告点击");
}
@Override
public void onAdShow() {
Log.i(TAG, "广告成功展示");
}
@Override
public void onAdClose() {
Log.i(TAG, "广告关闭");
if (viewGroup != null) {
viewGroup.removeAllViews();
}
}
@Override
public void onRenderFail(int code, String msg) {
Log.e(TAG, "广告渲染失败,code = " + code + ", msg = " + msg);
}
@Override
public void onRenderSuccess(View view) {
Log.i(TAG, "广告渲染成功");
if (viewGroup != null && view != null) {
viewGroup.removeAllViews();
viewGroup.addView(view);
}
}
}); //setExpressFeedAdInteractionListener end
saExpressFeedAd.render(); //广告渲染
}
} //loadSAExpressFeedAd end
@Override
public void onError(int code, String message)
Log.e(TAG, "广告加载失败,code = " + code + ", msg = " + message);
}
@Override
public void onResourceLoad() {
}
}); //loadSAExpressFeedAd end
}
开发者自渲染
当优推SDK提供的原生模版渲染广告的样式和展示场景无法满足需求时,可以采用原生开发者自渲染广告
使用自渲染的API,您可以自定义广告的布局和展示场景。
使用SAAllianceAdSdk.getSAAllianceAdManager().createSAAllianceAd()
获取SAAllianceAd接口类型对象;
调用loadSANativeFeedAd(SAAllianceAdParams params, SANativeFeedAdLoadListener listener)
进行广告加载; 开发者通过自定义布局来渲染广告数据。
SAAllianceAd原生开发者自渲染广告相关方法说明
方法 | 说明 |
---|---|
加载原生开发者模版渲染广告 |
SANativeFeedAdLoadListener说明
方法 | 说明 |
---|---|
加载成功, | |
加载失败,code 错误码,message 错误信息 | |
广告素材加载成功 | |
void onTimeOut() | 加载超时 |
SAAllianceNativeFeedAdData说明
获取广告数据元素的方法说明
下载类广告合规6要素获取
当getLdpType()
的值为1时可用
获取视频播放组件
当getVideoUrl()
可以获取到正确的url时,可以调用NMPlayerView getNmApAdVideo(Context context)
获取视频播放组件。
视频组件事件监听NMAPAdNativeVideoViewListener:
方法 | 说明 |
---|---|
进行广告自渲染的方法
开发者自行创建广告布局,将获取到的 SAAllianceNativeFeedAdData 中的内容渲染到布局中后,调用
registerPACAViews(Activity activity, View selfRenderView, ArrayList<View> clickViews, NMNativeADEventListener listener)
方法
参数说明
说明 | 是否必填 | |
---|---|---|
所在的activity | 必填 | |
广告容器View | 必填,如果传入无效的值,则不会曝光成功,将无法获得收益 | |
可点击视图数组 | 必填 | |
广告事件监听 | 必填 |
NMNativeADEventListener说明
方法 | 说明 |
---|---|
void onAdExposed(); | 广告曝光 |
void onAdClicked(); | 广告点击 |
请求自渲染广告示例
private void getImgNativeFeedView(String posId, int width, int height) {
mViewContainer.removeAllViews();
SAAllianceAdParams params = new SAAllianceAdParams();
params.setPosId(posId);
params.setImageAcceptedWidth(width);//单位dp
params.setImageAcceptedHeight(height);//单位dp
saAllianceAd = SAAllianceAdSdk.getSAAllianceAdManager().createSAAllianceAd(FeedActivity.this);
saAllianceAd.loadSANativeFeedAd(params, new SANativeFeedAdLoadListener() {
@Override
public void onNativeFeedAdLoad(SAAllianceNativeFeedAdData nativeFeedAdData) {
if (nativeFeedAdData == null) {
return;
}
mNativeFeedAdData = nativeFeedAdData;
//获取ecpm
String ecpm = nativeFeedAdData.getECPM();
ViewGroup NativeView = DemoATNativeAdView.createLayout(context,nativeFeedAdData);
mViewContainer.addView(NativeView);
if(ecpm!=null) {
saAllianceAd.reportBiddingSucceed(true);
}
}
@Override
public void onError(int code, String message) {
saAllianceAd = null;
Log.e("ADallianceLog","onNativeFeedAdLoad: " +message);
Toast.makeText(FeedActivity.this, "自渲染广告加载失败, " + code + " - " + message, Toast.LENGTH_LONG).show();
}
@Override
public void onResourceLoad() {
}
});
}
package com.alliance.ssp.testdemo;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.alliance.ssp.R;
import com.alliance.ssp.ad.api.SAAllianceNativeFeedAdData;
import com.alliance.ssp.ad.imageloader.ImageLoader;
import com.alliance.ssp.ad.impl.nativefeed.NMPlayerView;
import com.alliance.ssp.ad.impl.nativefeed.NMNativeADEventListener;
import com.alliance.ssp.ad.utils.StringUtil;
import java.util.ArrayList;
import java.util.List;
public class DemoATNativeAdView {
static FrameLayout playerView;
static ImageView mNMAdAudioIv;
static TextView sixelement;//六要素文字
public static ViewGroup createLayout(Context context, SAAllianceNativeFeedAdData nativeFeedAdData) {
//加载布局
View selfRenderView = View.inflate(context, R.layout.layout_nmssp_express_feed_top_image_bottom_text_new_demo, null);
ImageView imgView = selfRenderView.findViewById(com.alliance.ssp.ad.R.id.iv_nm_express_feed_ad_img);//图片布局
TextView desc = selfRenderView.findViewById(R.id.tv_nm_express_feed_ad_desc);
TextView title = selfRenderView.findViewById(R.id.tv_nm_express_feed_ad_title);
sixelement = selfRenderView.findViewById(com.alliance.ssp.ad.R.id.tv_nm_express_feed_ad_sixelement);
//应用内下载广告底部加上三要素 H5-0 APP下载-1 DeepLink-2
if(nativeFeedAdData.getLdpType() == 1){
RelativeLayout iv_nm_express_feed_ad_three_element = selfRenderView.findViewById(com.alliance.ssp.ad.R.id.iv_nm_express_feed_ad_three_element);
iv_nm_express_feed_ad_three_element.setVisibility(View.VISIBLE);
boolean hasSixElement = true;
if (StringUtil.isEmpty(nativeFeedAdData.getApkName()) && StringUtil.isEmpty(nativeFeedAdData.getAppPublisher())
&& StringUtil.isEmpty(nativeFeedAdData.getVersionName()) && StringUtil.isEmpty(nativeFeedAdData.getAppIntro())
&& StringUtil.isEmpty(nativeFeedAdData.getPermissionUrl()) && StringUtil.isEmpty(nativeFeedAdData.getPrivacyUrl())) {
hasSixElement = false;
}
if (hasSixElement) {
String tempText = "";
if(nativeFeedAdData.getApkName()!=null&&nativeFeedAdData.getApkName().length()>0) {
String appname = nativeFeedAdData.getApkName();
if(appname.length()>10){
appname = appname.substring(0,10)+"..";
}
tempText += "应用名称: " + appname;
}
if(nativeFeedAdData.getVersionName()!=null&&nativeFeedAdData.getVersionName().length()>0) {
tempText += " | 应用版本: " + nativeFeedAdData.getVersionName();
}
if(nativeFeedAdData.getAppPublisher()!=null&&nativeFeedAdData.getAppPublisher().length()>0) {
String publisher = nativeFeedAdData.getAppPublisher();
if(publisher.length()>12){
publisher = publisher.substring(0,12)+"..";
}
tempText += " | 开发者: " + publisher;
}
String gongneng = "\n功能列表";
if(tempText.length() > 55){
gongneng = " | 功能列表";
}
String quanxian = " | 隐私权限";
String yinsi = " | 隐私协议";
SpannableString ss1 = new SpannableString(tempText + gongneng + quanxian + yinsi);
ClickableSpan span1 = new ClickableSpan() {
@Override
public void onClick(View textView) {
((TextView)textView).setHighlightColor(Color.TRANSPARENT);//方法重新设置文字背景为透明色。
Log.e("ADallianceLogXX", "span1 span1 span1 span1 span1 ");
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
ds.clearShadowLayer();
}
};
ClickableSpan span2 = new ClickableSpan() {
@Override
public void onClick(View textView) {
((TextView)textView).setHighlightColor(Color.TRANSPARENT);//方法重新设置文字背景为透明色。
Log.e("ADallianceLogXX", "span2 span1 span1 span1 span1 ");
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
ds.clearShadowLayer();
}
};
ClickableSpan span3 = new ClickableSpan() {
@Override
public void onClick(View textView) {
((TextView)textView).setHighlightColor(Color.TRANSPARENT);//方法重新设置文字背景为透明色。
Log.e("ADallianceLogXX", "span3 span1 span1 span1 span1 ");
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
ds.clearShadowLayer();
}
};
ss1.setSpan(span1,0+tempText.length(),gongneng.length()+tempText.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
ss1.setSpan(span2,0+tempText.length()+gongneng.length(),gongneng.length()+tempText.length()+quanxian.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
ss1.setSpan(span3,0+tempText.length()+gongneng.length()+quanxian.length(),gongneng.length()+tempText.length()+quanxian.length()+yinsi.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
sixelement.setMovementMethod(LinkMovementMethod.getInstance());
sixelement.setText(ss1);
iv_nm_express_feed_ad_three_element.setVisibility(View.VISIBLE);
}
}
mNMAdAudioIv = selfRenderView.findViewById(com.alliance.ssp.ad.R.id.iv_nm_splash_audio_switch);
playerView = selfRenderView.findViewById(com.alliance.ssp.ad.R.id.videoview);
RelativeLayout iv_nm_express_feed_ad_layout_img= selfRenderView.findViewById(R.id.iv_nm_express_feed_ad_layout_img);
RelativeLayout iv_nm_express_feed_ad_layout_video= selfRenderView.findViewById(R.id.iv_nm_express_feed_ad_layout_video);
String videoUrl = nativeFeedAdData.getVideoUrl();
// 创建一个frame布局
FrameLayout frameLayout = new FrameLayout(context);
frameLayout.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
if(videoUrl!=null&&videoUrl.length()!=0){
iv_nm_express_feed_ad_layout_video.setVisibility(View.VISIBLE);
iv_nm_express_feed_ad_layout_img.setVisibility(View.GONE);
loadVideo(videoUrl, context, frameLayout, nativeFeedAdData, nativeFeedAdData.getECPM());
}else {
//Button button = selfRenderView.findViewById(R.id.iv_nm_but);
List<String> imgUrlList = nativeFeedAdData.getImgUrl();
String desc_ = nativeFeedAdData.getDesc();
if (desc_ != null && desc_.length() != 0) {
desc.setText(desc_);
}
String title_ = nativeFeedAdData.getTitle();
if (title_ != null && title_.length() != 0) {
title.setText(title_);
}
ImageLoader.getInstance().displayImage(imgUrlList.get(0), new ImageLoader.ImageLoadListener() {
@Override
public void onSuccess(String imgUrl, Bitmap bitmap) {
imgView.setImageBitmap(bitmap);
ArrayList<View> clickViews = new ArrayList<>();
clickViews.add(selfRenderView);
//注册点击和展示view
nativeFeedAdData.registerPACAViews(context, selfRenderView, clickViews, new NMNativeADEventListener(){
@Override
public void onAdExposed() {
Log.e("ADallianceLog","NMNativeADEventListener onAdExposed = ");
Toast.makeText(context, "Feed广告展示 ...ecpm " + nativeFeedAdData.getECPM(), Toast.LENGTH_LONG).show();
//bannerView = null;
}
@Override
public void onAdClicked() {
Log.e("ADallianceLog","NMNativeADEventListener onAdClicked = ");
Toast.makeText(context, "Feed广告点击 ... ", Toast.LENGTH_LONG).show();
}
});
}
@Override
public void onFailed(String imgUrl, Exception ex) {
}
});
ImageView logoView = nativeFeedAdData.getLogoView(context);
frameLayout.addView(selfRenderView);
frameLayout.addView(logoView);
}
return frameLayout;
}
private static void loadVideo(String url_,Context context,ViewGroup frameLayout,SAAllianceNativeFeedAdData nativeFeedAdData,String price){
if(nativeFeedAdData.getNmApAdVideo(context) != null) {
NMPlayerView videoView = nativeFeedAdData.getNmApAdVideo(context);
if (videoView != null) {
videoView.showVideo(frameLayout);
videoView.setNMApAdNativeVideoviewListener(new NMPlayerView.NMAPAdNativeVideoViewListener() {
@Override
public void onVideoLoading() {
Log.e("ADallianceLog","NMAPAdNativeVideoViewListener onVideoLoading ======== ");
}
@Override
public void onVideoReady() {
Log.e("ADallianceLog","NMAPAdNativeVideoViewListener onVideoReady ======== ");
}
@Override
public void onVideoStart() {
Log.e("ADallianceLog","NMAPAdNativeVideoViewListener onVideoStart ======== ");
}
@Override
public void onVideoPause() {
Log.e("ADallianceLog","NMAPAdNativeVideoViewListener onVideoPause ======== ");
}
@Override
public void onVideoResume() {
Log.e("ADallianceLog","NMAPAdNativeVideoViewListener onVideoResume ======== ");
}
@Override
public void onVideoCompleted() {
Log.e("ADallianceLog","NMAPAdNativeVideoViewListener onVideoCompleted ======== ");
}
@Override
public void onVideoStop() {
Log.e("ADallianceLog","NMAPAdNativeVideoViewListener onVideoStop ======== ");
}
@Override
public void onVideoError(int errorType) {
Log.e("ADallianceLog","NMAPAdNativeVideoViewListener onVideoError ======== ");
}
});
}
}
ArrayList<View> clickViews = new ArrayList<>();
clickViews.add(frameLayout);
//注册点击和展示view
nativeFeedAdData.registerPACAViews(context, frameLayout, clickViews, new NMNativeADEventListener(){
@Override
public void onAdExposed() {
Log.e("ADallianceLog","NMNativeADEventListener onAdExposed2 = ");
Toast.makeText(context, "Feed广告展示 ...ecpm " + price, Toast.LENGTH_LONG).show();
}
@Override
public void onAdClicked() {
Log.e("ADallianceLog","NMNativeADEventListener onAdClicked2 = ");
Toast.makeText(context, "Feed广告点击 ... ", Toast.LENGTH_LONG).show();
}
});
}
}
layout_nmssp_express_feed_top_image_bottom_text_new_demo.xml布局文件实例
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/iv_nm_express_feed_ad_layout_img"
android:layout_weight="1">
<ImageView
android:id="@+id/iv_nm_express_feed_ad_img_back"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"/>
<ImageView
android:id="@+id/iv_nm_express_feed_ad_img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerInside"/>
<ImageView
android:id="@+id/iv_nm_logo"
android:layout_width="33.4dp"
android:layout_height="12.5dp"
android:layout_alignRight="@id/iv_nm_express_feed_ad_img"
android:layout_alignBottom="@id/iv_nm_express_feed_ad_img"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/iv_nm_express_feed_ad_layout_video"
android:visibility="gone"
android:layout_weight="1">
<ImageView
android:id="@+id/iv_nm_img_video_back"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"/>
<FrameLayout
android:id="@+id/videoview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/iv_nm_logo2"
android:layout_width="33.4dp"
android:layout_height="12.5dp"
android:layout_alignRight="@id/videoview"
android:layout_alignBottom="@id/videoview"/>
<ImageView
android:id="@+id/iv_nm_splash_audio_switch"
android:layout_width="35dp"
android:layout_height="35dp"
android:src="@drawable/nmadssp_audio_off"
android:layout_alignLeft="@id/videoview"
android:layout_alignBottom="@id/videoview" />
</RelativeLayout>
<TextView
android:id="@+id/tv_nm_express_feed_ad_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:layout_below="@id/iv_nm_express_feed_ad_img"
android:textSize="11sp"
app:autoSizeMaxTextSize="22sp"
app:autoSizeMinTextSize="4sp"
android:textColor="#222222"
android:layout_marginTop="0.2dp"
android:ellipsize="end"
android:maxLines="1"
android:includeFontPadding="false" />
<TextView
android:id="@+id/tv_nm_express_feed_ad_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:layout_below="@id/tv_nm_express_feed_ad_title"
android:textSize="11sp"
app:autoSizeMaxTextSize="22sp"
app:autoSizeMinTextSize="4sp"
android:textColor="#222222"
android:layout_marginTop="0.2dp"
android:ellipsize="end"
android:maxLines="1"
android:includeFontPadding="false" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:layout_marginTop="0.1dp">
<TextView
android:id="@+id/tv_nm_express_feed_ad_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:textColor="#222222"
android:textSize="10sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_alignParentRight="true"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_nm_express_feed_ad_check_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/nmadssp_check_info_bg"
android:text="@string/nm_check_info"
android:textSize="9sp"
android:textColor="#FF5500"
android:includeFontPadding="false"
android:layout_gravity="center"/>
<ImageView
android:id="@+id/iv_nm_express_feed_ad_more_selector"
android:layout_width="6.6dp"
android:layout_height="wrap_content"
android:layout_marginLeft="13.33dp"
android:src="@drawable/nmadssp_more_vertical"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>