Billowlink SDK Android 接入文档一、初始化二、广告加载1. 开屏广告1.1 加载广告1.2 展示广告1.3 销毁广告2. 插全屏广告2.1 加载广告2.2 展示广告2.3 销毁广告3. 激励广告3.1 加载广告3.2 展示广告3.3 销毁广告4. 信息流广告4.1 加载广告4.2 销毁广告三、第三方聚合中使用1. 聚合至 ToBid 使用1.1 自定义广告网络说明1.2 添加 Billowlink ToBid Adapter SDK 依赖1.3 自定义广告网络配置2. 聚合至 GroMore 使用2.1 自定义广告网络说明2.2 添加 Billowlink GroMore Adapter SDK 依赖2.3 自定义广告网络配置3. 聚合至 TradPlus 使用3.1 自定义广告网络说明3.2 添加 Billowlink TradPlus Adapter SDK 依赖3.3 自定义广告网络配置4. 聚合至 TopOn 使用4.1 自定义广告网络说明4.2 添加 Billowlink TopOn Adapter SDK 依赖4.3 自定义广告网络配置四、混淆配置附录:测试广告位隐私政策链接
在项目(Project)的 build.gradle
文件中添加以下依赖:
// Billowlink Maven 仓库地址
maven { url 'https://developer.billowlink.com/repository/repo/' }
在应用模块(Module)的 build.gradle
文件中添加以下依赖:
xxxxxxxxxx
// Billowlink SDK 依赖
implementation('com.billowlink.ads:android-sdk:1.1.3') {
// 如果出现以下依赖冲突可以选择性排除
//exclude group: 'androidx.appcompat', module: 'appcompat'
//exclude group: 'com.google.code.gson', module: 'gson'
//exclude group: 'com.huawei.hms', module: 'ads-identifier'
//exclude group: 'com.hihonor.mcs', module: 'ads-identifier'
}
在应用模块(Module)的 AndroidManifest.xml
文件中的添加如下权限:
xxxxxxxxxx
<!-- 网络相关权限(必选)-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 安装应用权限(可选),下载安装类广告使用 -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!-- 获取应用软件列表权限(可选),通过此权限在 Android R 系统上判定广告对应的应用是否在用户设备上安装,避免投放错误的广告,以此提高用户的广告体验,若添加此权限,需要在应用的用户隐私文档中声明 -->
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<!-- 读取 IMEI 设备标识(可选),广告投放监测归因,反作弊 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
在 Application 的 onCreate
方法中进行初始化:
xBillowAdConfig config = new BillowAdConfig.Builder()
.withAppId("your_app_id")
.withAppName("your_app_name")
.withDebug(false)
.withAllowNotify(true)
// 默认隐私配置
.withCustomController(new BillowDefaultCustomController())
.build();
BillowAdSdk.init(application, config, new InitialListener() {
public void onSucceed() {
// 初始化成功
Logger.d(TAG, "onSucceed");
}
public void onError(String msg) {
// 初始化失败
Logger.d(TAG, "onError: msg = " + msg);
}
});
隐私设置
xxxxxxxxxx
BillowAdConfig config = new BillowAdConfig.Builder()
.withAppId("your_app_id")
.withAppName("your_app_name")
.withDebug(false)
.withAllowNotify(true)
// 默认隐私配置
.withCustomController(new BillowCustomController() {
/**
* 是否允许获取位置
*/
public boolean isCanUseLocation() {
return false;
}
/**
* 是否允许查询已安装应用列表(开启可以提高广告填充)
*/
public boolean allowQueryAppList() {
return false;
}
/**
* 是否允许读取 IMEI
*/
public boolean isCanUsePhoneState() {
return false;
}
/**
* 支持 CP 传入 IMEI
*/
public String getImei() {
return "";
}
/**
* 是否允许读取 MAC 地址
*/
public boolean isCanUseWifiState() {
return false;
}
/**
* 支持 CP 传入 MAC 地址
*/
public String getMacAddress() {
return "";
}
/**
* 是否允许读取外部存储文件
*/
public boolean isCanUseWriteExternal() {
return false;
}
/**
* 支持 CP 传入 OAID
*/
public String getOaid() {
return "";
}
/**
* 是否允许读取 AndroidId
*/
public boolean isCanUseAndroidId() {
return false;
}
/**
* 支持 CP 传入 AndroidId
*/
public String getAndroidId() {
return "";
}
/**
* 个性化广告是否开启
*/
public boolean isPersonalizedAd() {
return false;
}
/**
* 下载类广告二次弹窗确认是否开启
*/
public boolean isDownloadConfirmation() {
return true;
}
})
.build();
xxxxxxxxxx
import android.content.Intent;
import android.view.ViewGroup;
import com.billow.ad.demo.R;
import com.billow.demo.base.BaseActivity;
import com.billow.demo.constant.AdConstant;
import com.billow.demo.log.Logger;
import com.billow.sdk.http.common.AdError;
import com.billow.sdk.splash.SplashAd;
import com.billow.sdk.splash.SplashAdListener;
public class SplashActivity extends BaseActivity {
public static final String TAG = SplashActivity.class.getSimpleName();
SplashAd splashAd = new SplashAd(getActivity(), "your_splash_palcement_id");
protected int getLayoutId() {
return R.layout.activity_splash;
}
protected void initData() {
initAd();
}
private void initAd() {
ViewGroup adContainer = findViewById(R.id.ll_ad);
adContainer.removeAllViews();
splashAd.setAdListener(new SplashAdListener() {
/**
* 广告加载成功
*/
public void onAdLoaded() {
// 千次展现单价,单位:人民币分
Integer ecpm = mSplashAd.getEcpm();
String placementId = mSplashAd.getPlacementId();
Logger.d(TAG, "onAdLoaded: ecpm = " + ecpm + ", placementId = " + placementId);
}
/**
* 广告加载失败
*/
public void onAdLoadError(AdError error) {
Integer code = error.getErrorCode();
String message = error.getErrorMessage();
Logger.e(TAG, "onAdLoadError: code = " + code + ", message = " + message);
goHomeActivity();
}
/**
* 广告展示错误
*/
public void onAdPlayError(AdError error) {
Integer code = error.getErrorCode();
String message = error.getErrorMessage();
Logger.e(TAG, "onAdPlayError: code = " + code + ", message = " + message);
goHomeActivity();
}
/**
* 广告点击
*/
public void onAdClicked() {
Logger.i(TAG, "onAdClicked");
}
/**
* 广告展示成功
*/
public void onAdShown() {
Logger.i(TAG, "onAdShown");
}
/**
* 广告关闭
*/
public void onAdClosed() {
Logger.i(TAG, "onAdClosed");
goHomeActivity();
}
});
// 广告素材宽高,单位:像素
//splashAd.setWidthAndHeight(1280, 720);
// 最低千次展现单价,单位:人民币分
//splashAd.setBidFloor(1000);
//Map<String, Object> options = new HashMap<>();
//mSplashAd.setExt(options);
splashAd.loadAd();
}
private void goHomeActivity() {
if (isFinishing() || isDestroyed()) {
return;
}
startActivity(new Intent(getActivity(), MainActivity.class));
finish();
}
protected void onDestroy() {
super.onDestroy();
// 销毁广告
splashAd.destroy();
}
}
在onAdLoaded
回调中展示广告:
xxxxxxxxxx
if (splashAd.isReady()) {
adContainer.removeAllViews();
// 在广告容器中展示广告
splashAd.showAd(adContainer);
// 全屏展示广告
//splashAd.showAd(SplashActivity.this);
}
xxxxxxxxxx
public void onDestroy() {
super.onDestroy();
if (splashAd == null) {
return;
}
splashAd.destroy();
}
xxxxxxxxxx
import com.billow.ad.demo.R;
import com.billow.demo.base.BaseActivity;
import com.billow.demo.constant.AdConstant;
import com.billow.demo.log.Logger;
import com.billow.sdk.http.common.AdError;
import com.billow.sdk.interstitial.InterstitialAd;
import com.billow.sdk.interstitial.InterstitialAdListener;
public class InterstitialActivity extends BaseActivity {
public static final String TAG = InterstitialActivity.class.getSimpleName();
InterstitialAd interstitialAd = new InterstitialAd(getActivity(), "your_interstitial_palcement_id");
protected int getLayoutId() {
return R.layout.activity_interstitial;
}
protected void initData() {
initAd();
}
private void initAd() {
interstitialAd.setAdListener(new InterstitialAdListener() {
/**
* 视频素材广告播放完成(图片素材广告不会回调)
*/
public void onAdPlayedCompleted() {
Logger.i(TAG, "onAdPlayedCompleted");
}
public void onAdLoaded() {
Integer ecpm = mSplashAd.getEcpm();
String placementId = mSplashAd.getPlacementId();
Logger.d(TAG, "onAdLoaded: ecpm = " + ecpm + ", placementId = " + placementId);
}
public void onAdLoadError(AdError error) {
Integer code = error.getErrorCode();
String message = error.getErrorMessage();
Logger.e(TAG, "onAdLoadError: code = " + code + ", message = " + message);
}
public void onAdPlayError(AdError error) {
Integer code = error.getErrorCode();
String message = error.getErrorMessage();
Logger.e(TAG, "onAdPlayError: code = " + code + ", message = " + message);
}
public void onAdShown() {
Logger.i(TAG, "onAdShown");
}
public void onAdClicked() {
Logger.i(TAG, "onAdClicked");
}
public void onAdClosed() {
Logger.i(TAG, "onAdClosed");
}
});
interstitialAd.loadAd();
}
protected void onDestroy() {
super.onDestroy();
interstitialAd.destroy();
}
}
在onAdLoaded
回调中或者其它需要展示广告的地方调用:
xxxxxxxxxx
if (interstitialAd.isReady()) {
interstitialAd.showAd(InterstitialActivity.this);
}
xxxxxxxxxx
public void onDestroy() {
super.onDestroy();
if (interstitialAd == null) {
return;
}
interstitialAd.destroy();
}
xxxxxxxxxx
import com.billow.ad.demo.R;
import com.billow.demo.base.BaseActivity;
import com.billow.demo.constant.AdConstant;
import com.billow.demo.log.Logger;
import com.billow.sdk.http.common.AdError;
import com.billow.sdk.rewarded.RewardedAd;
import com.billow.sdk.rewarded.RewardedAdListener;
public class RewardedAdActivity extends BaseActivity {
public static final String TAG = RewardedAdActivity.class.getSimpleName();
RewardedAd rewardedAd = new RewardedAd(getActivity(), "your_rewarded_palcement_id"");
protected final int millisecond = 5000;
protected final Handler handler = new Handler(Looper.getMainLooper());
protected int getLayoutId() {
return R.layout.activity_main;
}
protected void initData() {
initAd();
}
private void initAd() {
rewardedAd.setAdListener(new RewardedAdListener() {
public void onAdLoaded() {
Integer ecpm = mSplashAd.getEcpm();
String placementId = mSplashAd.getPlacementId();
Logger.d(TAG, "onAdLoaded: ecpm = " + ecpm + ", placementId = " + placementId);
}
public void onAdLoadError(AdError error) {
Integer code = error.getErrorCode();
String message = error.getErrorMessage();
Logger.e(TAG, "onAdLoadError: code = " + code + ", message = " + message);
// 广告加载失败后再次请求,间隔 N 秒后重新请求,避免出现频繁请求
handler.postDelayed(() -> {
Logger.d(TAG, "onAdLoadError: 重新请求激励广告");
rewardedAd.loadAd();
}, millisecond);
}
public void onAdPlayError(AdError error) {
Integer code = error.getErrorCode();
String message = error.getErrorMessage();
Logger.e(TAG, "onAdPlayError: code = " + code + ", message = " + message);
// 广告展示失败后再次请求
handler.postDelayed(() -> {
Logger.d(TAG, "onAdPlayError: 重新请求激励广告");
rewardedAd.loadAd();
}, 1000);
}
public void onAdClicked() {
Logger.i(TAG, "onAdClicked");
}
public void onAdShown() {
Logger.i(TAG, "onAdShown");
}
/**
* 广告播放完成
*/
public void onAdPlayedCompleted() {
Logger.i(TAG, "onAdPlayedCompleted");
}
/**
* 获得激励
*/
public void onAdRewarded() {
Logger.i(TAG, "onAdRewarded");
}
public void onAdClosed() {
Logger.i(TAG, "onAdClosed");
}
});
rewardedAd.loadAd();
}
protected void onDestroy() {
super.onDestroy();
rewardedAd.destroy();
handler.removeCallbacksAndMessages(null);
}
}
在onAdLoaded
回调中或者其它需要展示广告的地方调用:
xxxxxxxxxx
if (rewardedAd.isReady()) {
rewardedAd.showAd(RewardedAdActivity.this);
}
xxxxxxxxxx
public void onDestroy() {
super.onDestroy();
if (rewardedAd == null) {
return;
}
rewardedAd.destroy();
}
xxxxxxxxxx
private final List<NativeAd> nativeAds = new ArrayList<>();
NativeAd nativeAd = new NativeAd(getActivity(), placementId);
// 将广告添加至集合中后续统一销毁
nativeAds.add(nativeAd);
nativeAd.setAdListener(new NativeAdListener() {
public void onAdRendered(View nativeView, int width, int height) {
Logger.i(TAG, "onAdRendered: nativeView = " + nativeView + ", width = " + width + ", height = " + height);
if (nativeView == null) {
return;
}
// 添加广告进行展示
container.addView(nativeView);
}
public void onAdRenderError(AdError error) {
int code = error.getErrorCode();
String message = error.getErrorMessage();
Logger.e(TAG, "onAdRenderError: code = " + code + ", message = " + message);
}
public void onAdLoaded() {
Integer ecpm = nativeAd.getEcpm();
String placementId = nativeAd.getPlacementId();
Logger.d(TAG, "onAdLoaded: ecpm = " + ecpm + ", placementId = " + placementId);
if (nativeAd.isReady()) {
// 渲染广告,在 onAdRendered 回调中添加广告视图展示
nativeAd.renderAd();
}
}
public void onAdLoadError(AdError error) {
Integer code = error.getErrorCode();
String message = error.getErrorMessage();
Logger.e(TAG, "onAdLoadError: code = " + code + ", message = " + message);
}
public void onAdPlayError(AdError error) {
Integer code = error.getErrorCode();
String message = error.getErrorMessage();
Logger.e(TAG, "onAdPlayError: code = " + code + ", message = " + message);
}
public void onAdShown() {
Logger.i(TAG, "onAdShown");
}
public void onAdClicked() {
Logger.i(TAG, "onAdClicked");
}
public void onAdClosed() {
Logger.i(TAG, "onAdClosed");
}
});
nativeAd.setAdDownloadListener(new AdDownloadListener() {
/**
* 开始安装
*/
public void onInstallStart(String packageName, String appName) {
Logger.i(TAG, "onInstallStart: packageName = " + packageName + ", appName = " + appName);
}
/**
* 安装完成
*/
public void onInstalled(String packageName, String appName) {
Logger.i(TAG, "onInstalled: packageName = " + packageName + ", appName = " + appName);
}
/**
* 打开应用
*/
public void onAppOpen(String packageName, String appName) {
Logger.i(TAG, "onAppOpen: packageName = " + packageName + ", appName = " + appName);
}
/**
* 下载开始
*
* @param totalBytes 文件总大小
* @param currBytes 当前已下载的大小
* @param filename 文件名
*/
public void onStart(long totalBytes, long currBytes, String filename) {
int progress = (int) (currBytes * 100 / totalBytes);
Logger.i(TAG, "onStart: totalBytes = " + totalBytes
+ ", currBytes = " + currBytes
+ ", progress = " + progress
+ ", filename = " + filename);
}
/**
* 下载暂停
*
* @param totalBytes 文件总大小
* @param currBytes 当前已下载的大小
* @param filename 文件名
*/
public void onPaused(long totalBytes, long currBytes, String filename) {
int progress = (int) (currBytes * 100 / totalBytes);
Logger.i(TAG, "onPaused: totalBytes = " + totalBytes
+ ", currBytes = " + currBytes
+ ", progress = " + progress
+ ", filename = " + filename);
}
/**
* 下载进度更新
*
* @param totalBytes 文件总大小
* @param currBytes 当前已下载的大小
* @param filename 文件名
*/
public void onProgress(long totalBytes, long currBytes, String filename) {
int progress = (int) (currBytes * 100 / totalBytes);
Logger.i(TAG, "onProgress: totalBytes = " + totalBytes
+ ", currBytes = " + currBytes
+ ", progress = " + progress
+ ", filename = " + filename);
}
/**
* 下载完成
*
* @param downloadFile 下载的文件
* @param filename 文件名
*/
public void onCompleted(File downloadFile, String filename) {
Logger.i(TAG, "onCompleted: downloadFile = " + downloadFile.getAbsolutePath()
+ ", filename = " + filename);
}
/**
* 下载失败
*
* @param e 下载异常
* @param filename 文件名
*/
public void onFailed(Exception e, String filename) {
String message = e.getMessage();
Logger.e(TAG, "onFailed: message = " + message + ", filename = " + filename);
}
});
// 广告素材宽高,单位像素
//nativeAd.setWidthAndHeight(1280, 720);
// 最低千次展现单价,单位人民币分
//nativeAd.setBidFloor(1000);
//nativeAd.setExt(new HashMap<>());
nativeAd.loadAd();
xxxxxxxxxx
public void onDestroy() {
super.onDestroy();
for (NativeAd nativeAd : nativeAds) {
if (nativeAd == null) {
continue;
}
nativeAd.destroy();
}
}
在应用模块(Module)的 build.gradle
文件中添加以下依赖:
xxxxxxxxxx
// Billowlink ToBid Adapter SDK 依赖
implementation('com.billowlink.adapter:tobid-android-sdk:1.1.3') {
// 如果出现以下依赖冲突可以选择性排除
//exclude group: 'androidx.appcompat', module: 'appcompat'
//exclude group: 'com.billowlink.ads', module: 'android-sdk'
}
打开管理自定义广告网络页面(https://dash.sigmob.com/#/mediation/ad-networks),选择 Android 平台进行配置
xxxxxxxxxx
初始化类:com.billow.adapter.tobid.BillowCustomAdapterProxy
激励视频:com.billow.adapter.tobid.BillowCustomRewardedAdapter
开屏广告:com.billow.adapter.tobid.BillowCustomSplashAdapter
插屏广告:com.billow.adapter.tobid.BillowCustomInterstitialAdapter
原生广告:com.billow.adapter.tobid.BillowCustomNativeAdapter
以上配置完成后参考【ToBid 自定义广告网络说明】文档填写在 Billowlink 广告平台申请的 appId 以及 placementId
https://www.csjplatform.com/union/media/union/download/detail?id=147&docId=28006&osType=android
在应用模块(Module)的 build.gradle
文件中添加以下依赖:
xxxxxxxxxx
// Billowlink GroMore Adapter SDK 依赖
implementation('com.billowlink.adapter:gromore-android-sdk:1.1.3') {
// 如果出现以下依赖冲突可以选择性排除
//exclude group: 'androidx.appcompat', module: 'appcompat'
//exclude group: 'com.billowlink.ads', module: 'android-sdk'
}
打开管理自定义广告网络页面(https://www.csjplatform.com/union/media/union/mediation/netWorks),选择 Android 平台进行配置
xxxxxxxxxx
初始化类:com.billow.adapter.gromore.BillowCustomInitLoader
激励视频:com.billow.adapter.gromore.BillowCustomRewardedLoader
开屏广告:com.billow.adapter.gromore.BillowCustomSplashLoader
插屏广告:com.billow.adapter.gromore.BillowCustomInterstitialLoader
原生广告:com.billow.adapter.gromore.BillowCustomNativeLoader
以上配置完成后参考【GroMore 自定义广告网络说明】文档填写在 Billowlink 广告平台申请的 appId 以及 placementId
https://docs.tradplusad.com/docs/tradplussdk_android_doc_v6/tradplus_sdk_overview/customnetwork/info
在应用模块(Module)的 build.gradle
文件中添加以下依赖:
xxxxxxxxxx
// Billowlink TradPlus Adapter SDK 依赖
implementation('com.billowlink.adapter:tradplus-android-sdk:1.1.3') {
// 如果出现以下依赖冲突可以选择性排除
//exclude group: 'androidx.appcompat', module: 'appcompat'
//exclude group: 'com.billowlink.ads', module: 'android-sdk'
}
打开管理自定义广告网络页面(https://developer.tradplusad.com/network),选择 Android 平台进行配置
xxxxxxxxxx
激励视频:com.billow.adapter.tradplus.BillowCustomRewardedAdapter
开屏广告:com.billow.adapter.tradplus.BillowCustomSplashAdapter
插屏广告:com.billow.adapter.tradplus.BillowCustomInterstitialAdapter
原生广告:com.billow.adapter.tradplus.BillowCustomNativeAdapter
以上配置完成后参考【TradPlus 自定义广告网络说明】文档填写在 Billowlink 广告平台申请的 appId 以及 placementId,参数格式如下
xxxxxxxxxx
{"appId":"000000","placementId":"xxxxxxxx"}
https://newdocs.toponad.com/docs/fRMh7C
在应用模块(Module)的 build.gradle
文件中添加以下依赖:
xxxxxxxxxx
// Billowlink TopOn Adapter SDK 依赖
implementation('com.billowlink.adapter:topon-android-sdk:1.1.3') {
// 如果出现以下依赖冲突可以选择性排除
//exclude group: 'androidx.appcompat', module: 'appcompat'
//exclude group: 'com.billowlink.ads', module: 'android-sdk'
}
打开管理自定义广告网络页面(https://app.toponad.com/m/network),添加广告平台进行配置
xxxxxxxxxx
激励视频:com.billow.adapter.topon.BillowCustomRewardedAdapter
开屏广告:com.billow.adapter.topon.BillowCustomSplashAdapter
插屏广告:com.billow.adapter.topon.BillowCustomInterstitialAdapter
原生广告:com.billow.adapter.topon.BillowCustomNativeAdapter
以上配置完成后参考【TopOn 自定义广告网络说明】文档填写在 Billowlink 广告平台申请的 appId 以及 placementId,参数格式如下
xxxxxxxxxx
{"appId":"000000","placementId":"xxxxxxxx"}
xxxxxxxxxx
-dontwarn com.billow.**
-keep class com.billow.**{ *;}
-keep interface com.billow.**{ *;}
xxxxxxxxxx
public class AdConstant {
/**
* 开屏广告位(横竖屏适配)
*/
public static final String SPLASH_PLACEMENT_ID = "testtyIazksp01";
/**
* 激励广告位
*/
public static final String REWARDED_PLACEMENT_ID = "testtyIazkrv01";
/**
* 插屏广告位(半屏)
*/
public static final String INTERSTITIAL_HALF_PLACEMENT_ID = "testtyIazins01";
/**
* 插屏广告位(全屏)
*/
public static final String INTERSTITIAL_FULL_PLACEMENT_ID = "testtyIazins02";
/**
* 信息流横版样式广告位
*/
public static final String NATIVE_AD_STYLE_HORIZONTAL_PLACEMENT_ID = "testtyIazkto01";
/**
* 信息流竖版样式广告位
*/
public static final String NATIVE_AD_STYLE_VERTICAL_PLACEMENT_ID = "testtyIazkto02";
/**
* 信息流小图样式广告位
*/
public static final String NATIVE_AD_STYLE_SMALL_PLACEMENT_ID = "testtyIazkto03";
}