自定义C2SBidding广 告
一、流程说明
TradPlusSDK也支持自定义的C2SBidding广告方便您使用我们服务器的bidding竞价功能。
C2SBidding和普通自定义广告差别在于加载流程。广告展示流程是一致的。
C2SBidding的加载流程如图:
⚠️ 返回给TradPlusSDK的ECPM单位需要与TradPlus后台自定义广告源选择的货币单位保持一致
二、集成说明
1、创建自定义Adapter
- 创建您在 TradPlus后台定义的自定义类,继承 TradPlusBaseAdapter并重写相关方法
// 以百度激励视频C2S为例,自定义类名 BaiduIntersititalVideoC2SAdapter继承TPRewardAdapter
public class BaiduIntersititalVideoC2SAdapter extends TPRewardAdapter {
...
}
2、实现TradPlusSDK相关调用
- "getC2SBidding",SDK开始竞价流程,自定义Adapter需要从三方SDK相关接口获取ECPM。
- "isBiddingLoaded",竞价已经结束,成功获取ECPM
- 获取失败,用"onC2SBiddingFailed(String code, String msg)"将错误原因回传给TradPlusSDK
- 获取成功,用"onC2SBiddingResult(map)",将price(美金)put到map中回传给TradPlusSDK
public class BaiduIntersititalVideoC2SAdapter extends TPRewardAdapter {
private OnC2STokenListener onC2STokenListener;
private boolean isBiddingLoaded;
// 第一步:发起C2SBidding请求
@Override
public void getC2SBidding(final Context context, final Map<String, Object> localParams, final Map<String, String> tpParams, final OnC2STokenListener onC2STokenListener) {
this.onC2STokenListener = onC2STokenListener;
loadCustomAd(context, localParams, tpParams);
}
@Override
public void loadCustomAd(Context context, Map<String, Object> userParams, Map<String, String> tpParams) {
// userParams 本地配置参数;tpParams 服务器下发参数
// 获取服务器下发参数
...
// 初始化BaiduSDK
...
// 请求广告
requestAd(context);
}
private void requestAd(Context context) {
// 第三步:竞价成功后的通知TradPlusSDK加载成功
if (onC2STokenListener != null && isBiddingLoaded) {
if (mLoadAdapterListener != null) {
mLoadAdapterListener.loadAdapterLoaded(null);
}
return;
}
// 第二步:根据三方文档获取ECPM
RewardVideoAd mRewardVideoAd = new RewardVideoAd(context, "unitId",
new RewardVideoAd.RewardVideoAdListener() {
@Override
public void onVideoDownloadSuccess() {
Log.i(TAG, "视频缓存成功");
if (onC2STokenListener != null) {
// 根据三方文档,loaded成功后获取ECPM
String ecpmLevel = mRewardVideoAd.getECPMLevel();
if (TextUtils.isEmpty(ecpmLevel)) {
//价格返回空,无意义,通过onC2STokenListener调用失败回调
onC2STokenListener.onC2SBiddingFailed("", "ecpmLevel is Empty");
return;
}
// 成功获取price,通过onC2STokenListener将价格传给TradPlusSDK(美金)
Map<String, Object> hashMap = new HashMap<>();
// key必须是"ecpm",value是double类型
hashMap.put("ecpm", Double.parseDouble(ecpmLevel));
onC2STokenListener.onC2SBiddingResult(hashMap);
}
isBiddingLoaded = true;
}
@Override
public void onVideoDownloadFailed() {
Log.i(TAG, "视频缓存失败");
// 根据三方文档,失败无法获取ecpm,将失败原因回传给TradPlusSDK
if (onC2STokenListener != null) {
onC2STokenListener.onC2SBiddingFailed("", "视频缓存失败");
}
}
// ...
}, false);
mRewardVideoAd.load();
}
}
三、C2SBidding示例说明
C2SBidding获取ECPM并加载广告的流程一般有两种:
-
常见流程:广告和ECPM同时拿到,例如:百度的C2SBidding
-
其他流程:先获取ECPM,竞价成功后在请求获取广告,例如:InMobi的横幅和插屏
1、广告和ECPM同时拿到的示例
- 在三方广告对象加载完成后获取ECPM
// 百度激励视频
private RewardVideoAd mRewardVideoAd;
...
// 按照百度文档请求广告,loaded成功后同时可获取ECPM
mRewardVideoAd = new RewardVideoAd(context, "unitId",
new RewardVideoAd.RewardVideoAdListener() {
@Override
public void onVideoDownloadSuccess() {
Log.i(TAG, "视频缓存成功");
if (onC2STokenListener != null) {
// 根据三方文档,loaded成功后获取ECPM
String ecpmLevel = mRewardVideoAd.getECPMLevel();
if (TextUtils.isEmpty(ecpmLevel)) {
//价格返回空,无意义,通过onC2STokenListener调用失败回调
onC2STokenListener.onC2SBiddingFailed("", "ecpmLevel is Empty");
return;
}
// 成功获取price,通过onC2STokenListener将价格传给TradPlusSDK(美金)
Map<String, Object> hashMap = new HashMap<>();
// key必须是"ecpm",value是double类型
hashMap.put("ecpm", Double.parseDouble(ecpmLevel));
onC2STokenListener.onC2SBiddingResult(hashMap);
}
isBiddingLoaded = true;
}
}
mRewardVideoAd.load();
- 竞价成功后的加载
// 由于之前的获取ECPM时三方广告对象已加载完成了,
// 以只需要在确认广告是有效后直接向TradPlusSDK返回加载完成就可以了。
if (onC2STokenListener != null && isBiddingLoaded) {
if (mLoadAdapterListener != null) {
mLoadAdapterListener.loadAdapterLoaded(null);
}
return;
}
2、先获取ECPM后请求广告的示例
- 拿价的时候没有广告,获得价格后,需要再次请求一下广告
//Inmobi插屏
private InMobiInterstitial inmobiInterstitialVideo;
...
@Override
public void getC2SBidding(final Context context, final Map<String, Object> localParams, final Map<String, String> tpParams, final OnC2STokenListener onC2STokenListener) {
// 初始化 Inmobi SDK
// 初始化成功后 请求bid
requestBid(context, localParams, tpParams, onC2STokenListener);
}
public void requestBid(final Context context, Map<String, Object> userParams, Map<String, String> tpParams, final OnC2STokenListener onC2STokenListener) {
// 获取服务器下发参数 "unitId"
...
// 请求
inmobiInterstitialVideo = new InMobiInterstitial(context, "unitId", new InterstitialAdEventListener() {
@Override
public void onAdFetchSuccessful(InMobiInterstitial ad, AdMetaInfo info) {
// 成功,获取price,通过onC2STokenListener将价格传给TradPlusSDK(美金)
double bid = info.getBid();
Map<String, Object> hashMap = new HashMap<>();
// key必须是"ecpm",value是double类型
hashMap.put("ecpm", bid);
onC2STokenListener.onC2SBiddingResult(hashMap);
}
@Override
public void onAdFetchFailed(InMobiInterstitial ad,InMobiAdRequestStatus status) {
// 失败,无法获取ecpm,将失败原因回传给TradPlusSDK
onC2STokenListener.onC2SBiddingFailed("", status.getMessage());
}
});
// Step to preload interstitial
inmobiInterstitialVideo.getPreloadManager().preload();
}
- 竞价成功后的加载
private InMobiInterstitial inmobiInterstitialVideo;
// 由于之前的获取ECPM时三方广告对象已经创建了
if (inmobiInterstitialVideo != null) {
inmobiInterstitialVideo.setListener(new InterstitialAdEventListener());
inmobiInterstitialVideo.getPreloadManager().load();
}
四、展示广告
// 百度激励视频为例
@Override // 检查是否有可用广告
public boolean isReady() {
// 根据三方文档判断是否有可用广告,如果三方无此方法,可用三方监听loaded回调作为判断
return mRewardVideoAd != null && mRewardVideoAd.isReady();
}
@Override
public void showAd() {
// 根据三方文档调用show方法,展示广告
if (mRewardVideoAd != null && mRewardVideoAd.isReady()) {
mRewardVideoAd.show();
} else {
if (mShowListener != null) {
mShowListener.onAdVideoError(new TPError(SHOW_FAILED));
}
}
}
五、通知三方竞价成功和竞价失败
- 竞价失败后SDK会调用setLossNotifications
/**
* 竞价失败时的上报接⼝ V10.1.0.1 support
* @param auctionPrice 胜出者的第⼀名价格,单位是美元
* @param auctionPriceCny 胜出者的第⼀名价格,单位是元(人民币)
* @param lossReason 竞价失败的原因 返回null,原因 竞价失败
*/
@Override
public void setLossNotifications(String auctionPrice, String auctionPriceCny, String lossReason) {
// auctionPrice和 auctionPriceCny均需要判空,部分平台规定不可以回传价格
}
- 竞价成功
@Override
public void showAd() {
// 调用三方展示API前,通知三方竞价成功
}
六、常见问题
-
怎么测试比较方便验证setLossNotifications通知
请求的tradplus后台广告位中介组并行数和缓存数都设置为1,除了自定义的广告源,再配置一个必定填充并且很高价的waterfall,比如admob设置999$。这种情况下,自定义接入的广告源应该必定竞价失败会回调loss通知。