Dirichlet 聚合SDK Android 接入文档
SDK 支持版本
- Dirichlet SDK 和 优量汇 (Tencent Ad SDK) 最低支持 Android 5.0(API level 21)
- 穿山甲 (Pangle) SDK 最低支持 Android 7.0(API level 24)
- 编译环境为 Android Studio
SDK 配置
Maven 仓库配置
在 project 级别的 build.gradle 文件中添加穿山甲 (Pangle) Maven 的引用:
allprojects {
repositories {
maven {
url 'https://artifact.bytedance.com/repository/pangle'
}
}
}
依赖配置
将 DirichletAD_Mediation_4.2.8.0.aar、DirichletAD_CSJ_Adapter_4.2.8.0.aar、DirichletAD_GDT_Adapter_4.2.8.0.aar 拷贝到游戏目录下的 src/main/libs 目录中。
在项目目录下 build.gradle 文件中添加代码:
repositories {
flatDir{
dirs 'src/main/libs'
}
}
dependencies {
implementation (name: "DirichletAD_Mediation_4.2.8.0", ext: "aar") // Dirichlet 聚合SDK(包含Dirichlet广告SDK)
implementation (name: "DirichletAD_CSJ_Adapter_4.2.8.0", ext: "aar") // 穿山甲 adapter SDK
implementation (name: "DirichletAD_GDT_Adapter_4.2.8.0", ext: "aar") // 优量汇 adapter SDK
implementation('com.pangle.cn:ads-sdk-pro:7.6.1.2') { // 穿山甲广告 SDK
exclude group: 'com.android.support'
}
implementation 'com.qq.e.union:union:4.690.1560' // 优量汇广告SDK
implementation 'com.squareup.okhttp3:okhttp:3.12.1'
implementation "com.android.support:appcompat-v7:28.0.0"
implementation "com.android.support:support-annotations:28.0.0"
implementation "com.android.support:support-v4:28.0.0"
implementation "com.github.bumptech.glide:glide:4.9.0"
implementation 'com.android.support:recyclerview-v7:28.0.0'
}
权限申请 & 清单配置
配置 AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 必须的权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 为了获取更精准的 推送数据,建议加上的权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!-- targetVersion 31 及以上建议加上这个权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<!-- 为了获取更好的广告体验,建议加上以下权限来获取用户信息 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- 加上下列权限可以提高广告的转化率 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
</manifest>
Android 代码混淆
聚合 SDK 已内置 R8/ProGuard 混淆规则(consumerProguardFiles),默认情况下无需额外添加 -keep / -dontwarn 配置。
若工程使用自定义混淆策略导致类被误删/误混淆,请根据构建或运行日志按需补充规则。
资源混淆配置
如果您的工程中接入了资源混淆插件 AndResGuard,需要在 build.gradle 中新增白名单配置:
andResGuard {
// 白名单配置,请参考demo中的 `whiteList.txt`
whiteList = [
"R.integer.min_screen_width_bucket",
"R.style.DialogAnimationUp",
"R.style.DialogAnimationRight",
"R.style.DialogFullScreen",
"R.drawable.gdt_*"
...
]
}
获取广告权限
在获取 IMEI 和地理位置信息时,需要用户授予权限。建议先询问权限,再进行初始化工作。
DirichletAdManager.get().requestPermissionIfNecessary(activity);
初始化
DirichletAdConfig config = new DirichletAdConfig.Builder()
.withMediaId(your_media_id) // 必选参数。为 Dirichlet ADN 注册的媒体 ID
.withMediaName(your_media_name) // 必选参数。为 Dirichlet ADN 注册的媒体名称
.withMediaKey(your_media_key) // 必选参数。媒体密钥,可以在 Dirichlet ADN 后台查看
.enableDebug(false) // 可选参数,是否打开 debug 调试信息输出:true 打开、false 关闭。默认 false 关闭
.withCustomController(new DirichletAdCustomController() {
// 是否允许 SDK 主动使用地理位置信息
@Override
public boolean isCanUseLocation() {
return enableGetLocation;
}
// 当 isCanUseLocation=false 时,可传入地理位置信息,DirichletAd 使 用您传入的地理位置信息
@Override
public DirichletAdLocation getDirichletAdLocation() {
return new DirichletAdLocation(longitude, latitude, accuracy);
}
// 是否允许 SDK 主动使用手机硬件参数,如 imei
@Override
public boolean isCanUsePhoneState() {
return enableGetPhoneState;
}
// 当 isCanUsePhoneState=false 时,可传入 imei 信息,DirichletAd 使用您传入的 imei 信息
@Override
public String getDevImei() {
return imei;
}
// 是否允许 SDK 主动使用 ACCESS_WIFI_STATE 权限
@Override
public boolean isCanUseWifiState() {
return enableGetWifiState;
}
// 是否允许 SDK 主动使用 WRITE_EXTERNAL_STORAGE 权限
@Override
public boolean isCanUseWriteExternal() {
return enableWriteExternal;
}
// 开发者可以传入 oaid
// 信通院 OAID 的相关采集——如何获取 OAID:
// 1. 移动安全联盟官网 http://www.msa-alliance.cn/
// 2. 信通院统一 SDK 下载 http://msa-alliance.cn/col.jsp?id=120
@Override
public String getDevOaid() {
return oaid;
}
// 是否允许 SDK 主动获取设备上应用安装列表的采集权限
@Override
public boolean alist() {
return enableGetAppList;
}
// 是否允许 SDK 主动获取 ANDROID_ID
@Override
public boolean isCanUseAndroidId() {
return enableGetAndroidId;
}
})
.build();
// context 为 application 的上下文
DirichletSdk.init(context, config, new DirichletSdk.InitListener() {
@Override
public void onInitSuccess() {
Log.d("DirichletSdk", "初始化成功");
}
@Override
public void onInitFail(int code, String msg) {
Log.d("DirichletSdk", "初始化失败: " + code + ", " + msg);
}
});
广告个性化设置
建议在 App 的广告设置或隐私设置中提供「个性化广 告」开关,并向用户说明:
- 开启后,SDK 会根据用户的使用情况展示更相关的广告。
- 关闭后,广告数量不变,用户仍会看到广告,但广告相关度可能降低。
当用户修改开关时,调用以下接口同步到 SDK。App 需要自行保存用户选择,并在下次启动后重新设置一次。
import com.tapsdk.tapad.group.DirichletSdk;
import com.tapsdk.tapad.group.constants.Constants;
public void setPersonalizedAdEnabled(boolean enabled) {
DirichletSdk.putMediaGlobalSettings(
Constants.Personalization.PERSONAL_ADS_TYPE,
enabled
? Constants.Personalization.PERSONAL_ADS_TYPE_ALLOW
: Constants.Personalization.PERSONAL_ADS_TYPE_LIMIT
);
}
广告通用接口
创建广告加载器
// 注意,一个 Activity 中只需要创建一个 DirichletAdNative 对象
DirichletAdNative adNative = DirichletAdManager.get().createAdNative(context);
广告请求参数
DirichletAdRequest request = new DirichletAdRequest.Builder()
.withSpaceId(spaceId) // 必填,广告位 id
.withUserId(user_id) // 选填,用户 ID(用于激励广告奖励验证)
.withExtra1(extra_info) // 选填,激励广告验证奖励时透传参数
.withRewardName(reward_name) // 选填,奖励的名称(激励广告)
.withRewardAmount(100) // 选填,奖励的数量(激励广告)
.withExpressViewAcceptedSize(width, height) // 选填,广告视图尺寸(开屏、Banner)
.withExpressImageAcceptedSize(width, height) // 选填,视频视图尺寸(信息流)
.build();
广告对象通用方法
// 所有广告对象都包含以下方法
class Dirichlet**Ad {
// 销毁广告
public void destroy();
// 广告是否有效
boolean isValid();
// 获取广告额外参数,例如广告唯一 track_id、价格等
Map<String, Object> getDirichletExtraInfo();
}
广告类型
激励视频广告
激励视频是一种全屏播放的视频广告,用户可以在观看完整的视频后获取奖励。
自动加载展示(推荐)
showRewardVideoAutoAd 接口将加载和展示合并为一次调用,内部自动管理广告缓存。若有可用缓存则立即展示,否则自动加载后展示。
DirichletAdRequest request = new DirichletAdRequest.Builder()
.withSpaceId(YOUR_SPACE_ID)
.withUserId("user_123")
.withRewardName("金币")
.withRewardAmount(100)
.build();
adNative.showRewardVideoAutoAd(request, new DirichletAdNative.RewardVideoAutoAdListener() {
@Override
public void onError(int code, String message) {
Log.e("DirichletAd", "激励视频加载/展示失败: " + code + ", " + message);
}
@Override
public void onAdShow() {
Log.d("DirichletAd", "激励视频展示");
}
@Override
public void onAdClose() {
Log.d("DirichletAd", "激励视频关闭");
}
@Override
public void onRewardVerify(boolean rewardVerify, int rewardAmount, String rewardName, int code, String msg) {
if (rewardVerify) {
Log.d("DirichletAd", "获得奖励: " + rewardAmount + " " + rewardName);
}
}
@Override
public void onAdClick() {
Log.d("DirichletAd", "激励视频点击");
}
});
手动加载展示
获取广告
// 构建广告请求
DirichletAdRequest request = new DirichletAdRequest.Builder()
.withSpaceId(YOUR_SPACE_ID) // 广告位 ID
.withUserId(user_123) // 用户 ID(用于奖励验证)
.withExtra1(extra_data) // 额外参数
.withRewardName("金币") // 奖励名称
.withRewardAmount(100) // 奖励数量
.build();
// 加载激励视频广告
adNative.loadRewardVideoAd(request, new DirichletAdNative.RewardVideoAdListener() {
@Override
public void onRewardVideoAdLoad(DirichletRewardVideoAd rewardVideoAd) {
// 广告加载成功
Log.d("DirichletAd", "激励视频广告加载成功");
// 可以展示广告
showRewardVideoAd(rewardVideoAd);
}
@Override
public void onError(int code, String message) {
// 广告加载失败
Log.e("DirichletAd", "激励视频广告加载失败: " + code + ", " + message);
}
});
播放
private void showRewardVideoAd(DirichletRewardVideoAd rewardVideoAd) {
if (rewardVideoAd != null && rewardVideoAd.isValid()) {
// 设置交互回调 listener,曝光、点击、关闭、奖励等回调事件
rewardVideoAd.setRewardAdInteractionListener(new DirichletRewardVideoAd.RewardAdInteractionListener() {
@Override
public void onAdShow() {
Log.d("DirichletAd", "激励视频广告曝光展示");
}
@Override
public void onAdClick() {
Log.d("DirichletAd", "激励视频广告点击");
}
@Override
public void onAdClose() {
Log.d("DirichletAd", "激励视频广告关闭");
}
@Override
public void onRewardVerify(boolean rewardVerify, int rewardAmount, String rewardName, int code, String msg) {
if (rewardVerify) {
Log.d("DirichletAd", "获得奖励: " + rewardAmount + ", " + rewardName);
// 发放奖励给用户
} else {
Log.d("DirichletAd", "奖励验证失败: " + code + ", " + msg);
}
}
});
// 展示激励广告
rewardVideoAd.showRewardVideoAd(activity);
}
}
Banner 广告
Banner 广告为固定尺寸的横幅广告,可以放置在页面的顶部或底部。
自动加载展示(推荐)
showBannerAutoAd 接口将加载和展示合并为一次调用,内部自动管理广告缓存与轮播。开发者只需提供广告容器,SDK 自动完成加载、展示和定时刷新。
ViewGroup bannerContainer = findViewById(R.id.banner_container);
DirichletAdRequest request = new DirichletAdRequest.Builder()
.withSpaceId(YOUR_BANNER_SPACE_ID)
.withSlideInternal(30) // 轮播间隔(秒),取值范围 30~120,默认 30
.build();
adNative.showBannerAutoAd(request, bannerContainer, new DirichletAdNative.BannerAutoAdListener() {
@Override
public void onError(int code, String message) {
Log.e("DirichletAd", "Banner 自动加载失败: " + code + ", " + message);
}
@Override
public void onAdShow() {
Log.d("DirichletAd", "Banner 展示");
}
@Override
public void onAdClick() {
Log.d("DirichletAd", "Banner 点击");
}
@Override
public void onAdClose() {
Log.d("DirichletAd", "Banner 关闭");
}
});
手动 加载展示
获取广告
DirichletAdRequest request = new DirichletAdRequest.Builder()
.withSpaceId(YOUR_BANNER_SPACE_ID)
.withExpressViewAcceptedSize(width, height)
.build();
adNative.loadBannerAd(request, new DirichletAdNative.BannerAdListener() {
@Override
public void onBannerAdLoad(DirichletBannerAd bannerAd) {
// Banner 广告加载成功
Log.d("DirichletAd", "Banner 广告加载成功");
showBannerAd(bannerAd);
}
@Override
public void onError(int code, String message) {
Log.e("DirichletAd", "Banner 广告加载失败: " + code + ", " + message);
}
});
播放
private void showBannerAd(DirichletBannerAd bannerAd) {
if (bannerAd != null) {
// 获取 Banner 视图
View bannerView = bannerAd.getBannerView();
if (bannerView != null) {
// 添加到容器中
ViewGroup container = findViewById(R.id.banner_container);
container.removeAllViews();
container.addView(bannerView);
// 设置交互监听
bannerAd.setBannerInteractionListener(new DirichletBannerAd.BannerInteractionListener() {
@Override
public void onAdShow() {
Log.d("DirichletAd", "Banner 广告展示");
}
@Override
public void onAdClick() {
Log.d("DirichletAd", "Banner 广告点击");
}
@Override
public void onAdClose() {
Log.d("DirichletAd", "Banner 广告关闭");
}
});
}
}
}
开屏广告
开屏广告为用户在进入 App 时展示的全屏广告。
开屏广告的展示和加载必须在同一个 Activity 中。
竖屏开屏广告 view 要求 width = 屏幕宽,height 需要 >= 75% 屏幕高,否则会影响计费。
横屏开屏广告 view 要求 width = 屏幕宽,height 需要 = 屏幕高,否则会影响计费。
自动加载展示(推荐)
showSplashAutoAd 接口将加载和展示合并为一次调用,内部自动管理广告缓存。若有可用缓存则立即展示,否则自动加载后展示。
ViewGroup splashContainer = findViewById(R.id.splash_container);
DirichletAdRequest request = new DirichletAdRequest.Builder()
.withSpaceId(YOUR_SPLASH_SPACE_ID)
.withExpressViewAcceptedSize(screenWidth, screenHeight)
.build();
adNative.showSplashAutoAd(request, splashContainer, new DirichletAdNative.SplashAutoAdListener() {
@Override
public void onError(int code, String message) {
Log.e("DirichletAd", "开屏自动加载失败: " + code + ", " + message);
goToMainActivity();
}
@Override
public void onAdShow() {
Log.d("DirichletAd", "开屏展示");
}
@Override
public void onAdClick() {
Log.d("DirichletAd", "开屏点击");
}
@Override
public void onAdClose() {
Log.d("DirichletAd", "开屏关闭");
goToMainActivity();
}
});
手动 加载展示
获取广告
DirichletAdRequest request = new DirichletAdRequest.Builder()
.withSpaceId(YOUR_SPLASH_SPACE_ID)
.withExpressViewAcceptedSize(screenWidth, screenHeight) // 设置开屏尺寸
.build();
adNative.loadSplashAd(request, new DirichletAdNative.SplashAdListener() {
@Override
public void onSplashAdLoad(DirichletSplashAd splashAd) {
Log.d("DirichletAd", "开屏广告加载成功");
showSplashAd(splashAd);
}
@Override
public void onError(int code, String message) {
Log.e("DirichletAd", "开屏广告加载失败: " + code + ", " + message);
// 跳转到主页面
goToMainActivity();
}
});
播放
private void showSplashAd(DirichletSplashAd splashAd) {
if (splashAd != null) {
splashAd.setSplashInteractionListener(new DirichletSplashAd.AdInteractionListener() {
@Override
public void onAdShow() {
Log.d("DirichletAd", "开屏广告展示");
}
@Override
public void onAdClick() {
Log.d("DirichletAd", "开屏广告点击");
}
@Override
public void onAdClose() {
Log.d("DirichletAd", "开屏广告关闭");
goToMainActivity();
}
});
ViewGroup splashContainer = findViewById(R.id.splash_container);
splashAd.show(splashContainer);
}
}
点击展开 Kotlin 完整示例代码
class SplashActivity: AppCompatActivity() {
private lateinit var splashModel: SplashViewModel
private lateinit var binding: ActivitySplashBinding
var isPortrait: Boolean = true
override fun onCreate(savedInstanceState: Bundle?) {
supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
super.onCreate(savedInstanceState)
binding = ActivitySplashBinding.inflate(layoutInflater)
setContentView(binding.root)
splashModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory())[SplashViewModel::class.java]
binding.splashModel = splashModel
binding.lifecycleOwner = this
binding.portraitSplashBtn.setOnClickListener {
loadAd(splashModel.portraitSplashId.value, true)
}
binding.landscapeSplashBtn.setOnClickListener {
loadAd(splashModel.landscapeSplashId.value, false)
}
binding.splashShowBtn.setOnClickListener {
splashModel.log.value = ""
ad?.let {
binding.splashContainer.visibility = View.VISIBLE
binding.splashLoadContainer.visibility = View.GONE
binding.splashContainer.layoutParams = FrameLayout.LayoutParams(width, height)
it.show(binding.splashContainer)
}
}
tapAdNative = DirichletAdManager.get().createAdNative(this)
}
var ad: DirichletSplashAd? = null
var width = LayoutParams.MATCH_PARENT
var height = LayoutParams.MATCH_PARENT
private lateinit var tapAdNative: DirichletAdNative
private fun loadAd(spaceId: String?, isPortrait: Boolean) {
width = UIUtils.getScreenWidthInPx(this)
height = UIUtils.getScreenHeightInPx(this)
if (isPortrait) {
height = width / 9 * 16
}
splashModel.log.value = ""
tapAdNative.loadSplashAd(
DirichletAdRequest.Builder()
.withSpaceId(spaceId?.toLong() ?: 0)
.withExpressViewAcceptedSize(width, height)
.build(), object: DirichletAdNative.SplashAdListener {
override fun onError(code: Int, message: String?) {
splashModel.log.postValue("加载失败,$code, $message")
}
override fun onSplashAdLoad(splashAd: DirichletSplashAd?) {
splashModel.log.postValue("加载成功")
this@SplashActivity.isPortrait = isPortrait
ad = splashAd
ad?.setSplashInteractionListener(object: DirichletSplashAd.AdInteractionListener {
override fun onAdClose() {
binding.splashContainer.removeAllViews()
binding.splashContainer.visibility = View.GONE
binding.splashLoadContainer.visibility = View.VISIBLE
}
override fun onAdClick() {
Toast.makeText(this@SplashActivity, "开屏广告点击", Toast.LENGTH_SHORT).show()
}
override fun onAdShow() {
}
})
}
})
}
/**
* 清理当前广告和相关引用
*/
private fun cleanupCurrentAd() {
ad?.destroy()
}
override fun onDestroy() {
super.onDestroy()
// 最终清理,确保所有引用都被释放
cleanupCurrentAd()
}
}
插屏广告
插屏广告支持「全屏视频广告」、「全屏图文广告」和「半屏图文广告」等形式。
插屏广告分横竖屏形式,强烈建议在 后台配置后正确使用横屏或竖屏广告,若用错配置的 orientation,可能会出现 UI 兼容异常问题。
自动加载展示(推荐)
showInterstitialAutoAd 接口将加载和展示合并为一次调用,内部自动管理广告缓存。若有可用缓存则立即展示,否则自动加载后展示。
DirichletAdRequest request = new DirichletAdRequest.Builder()
.withSpaceId(YOUR_INTERSTITIAL_SPACE_ID)
.build();
adNative.showInterstitialAutoAd(request, activity, new DirichletAdNative.InterstitialAutoAdListener() {
@Override
public void onError(int code, String message) {
Log.e("DirichletAd", "插屏自动加载失败: " + code + ", " + message);
}
@Override
public void onAdShow() {
Log.d("DirichletAd", "插屏展示");
}
@Override
public void onAdClick() {
Log.d("DirichletAd", "插屏点击");
}
@Override
public void onAdClose() {
Log.d("DirichletAd", "插屏关闭");
}
});
手动加载展示
获取广告
DirichletAdRequest request = new DirichletAdRequest.Builder()
.withSpaceId(YOUR_INTERSTITIAL_SPACE_ID)
.build();
adNative.loadInterstitialAd(request, new DirichletAdNative.InterstitialAdListener() {
@Override
public void onInterstitialAdLoad(DirichletInterstitialAd interstitialAd) {
Log.d("DirichletAd", "插屏广告加载成功");
showInterstitialAd(interstitialAd);
}
@Override
public void onError(int code, String message) {
Log.e("DirichletAd", "插屏广告加载失败: " + code + ", " + message);
}
});
播放
private void showInterstitialAd(DirichletInterstitialAd interstitialAd) {
if (interstitialAd != null && interstitialAd.isValid()) {
// 设置交互 listener
interstitialAd.setInteractionListener(new DirichletInterstitialAd.InterstitialAdInteractionListener() {
@Override
public void onAdShow() {
Log.d("DirichletAd", "插屏广告展示");
}
@Override
public void onAdClick() {
Log.d("DirichletAd", "插屏广告点击");
}
@Override
public void onAdClose() {
Log.d("DirichletAd", "插屏广告关闭");
}
});
interstitialAd.show(activity);
}
}
自渲染信息流广告
自渲染信息流广告为可自定义布局的信息流广告,包含大图和视频两种基本样式类型。
支持的广告尺寸:
- 大图(宽高比:1.78 的图片)
- 视频(宽高比:1.78 的视频)
获取广告
DirichletAdRequest request = new DirichletAdRequest.Builder()
.withSpaceId(YOUR_FEED_SPACE_ID)
.withExpressViewAcceptedSize(widthPx, heightPx) // 输入期待的父 view 的宽高
.withExpressImageAcceptedSize(widthPx, heightPx) // 输入期待的视频 view 的宽高
.build();
adNative.loadNativeFeedAd(request, new DirichletAdNative.NativeFeedAdListener() {
@Override
public void onNativeFeedAdLoad(List<DirichletNativeFeedAd> ads) {
Log.d("DirichletAd", "信息流广告加载成功,数量: " + ads.size());
for (DirichletNativeFeedAd ad : ads) {
bindNativeView(ad);
}
}
@Override
public void onError(int code, String message) {
Log.e("DirichletAd", "信息流广告加载失败: " + code + ", " + message);
}
});
广告行为监听 & 展示
AdInteractionListener 涉及到广告计费,必须正确调用,container 必须使用 DirichletAdNativeContainer。
private void bindNativeView(final DirichletNativeFeedAd ad) {
// 加载广告图标
Glide.with(binding.imgLogo).load(ad.getIconUrl()).into(binding.imgLogo);
// 设置广告标题和描述
binding.textTitle.setText(ad.getTitle());
binding.textDesc.setText(ad.getDescription());
// 添加视频 view
binding.videoContainer.removeAllViews();
View videoView = ad.getAdView();
ViewParent parent = videoView != null ? videoView.getParent() : null;
if (parent instanceof ViewGroup) {
((ViewGroup) parent).removeView(videoView);
}
binding.videoContainer.addView(ad.getAdView());
// 加载广告图片
Glide.with(binding.imgPoster)
.load(ad.getImageInfoList().get(0).getImageUrl())
.into(binding.imgPoster);
// 注册可点击的 View,click/show 会在内部完成
// container: 渲染广告最外层的 DirichletAdNativeContainer
// clickViews: 可点击的视图
// creativeViews: 可点击的创意视图(广告下载的按钮)
ad.registerViewForInteraction(
activity,
binding.nativeAdContainer,
Arrays.asList(binding.customContainer),
Arrays.asList(binding.btnDownload),
new DirichletNativeFeedAd.AdInteractionListener() {
@Override
public void onAdClick(View view, DirichletNativeFeedAd ad) {
Log.d("DirichletAd", "自渲染信息流点击");
}
@Override
public void onAdShow(DirichletNativeFeedAd ad) {
Log.d("DirichletAd", "自渲染信息流展示");
}
}
);
// 设置下载监听器
ad.setDownloadListener(new DirichletAppDownloadListener() {
@Override
public void onDownloadStart() {
Log.d("DirichletAd", "开始下载");
}
@Override
public void onDownloadComplete() {
Log.d("DirichletAd", "下载完成");
}
@Override
public void onUpdateDownloadProgress(int percent) {
Log.d("DirichletAd", "下载进度: " + percent);
}
@Override
public void onDownloadError() {
Log.d("DirichletAd", "下载错误");
}
@Override
public void onInstalled() {
Log.d("DirichletAd", "安装完成");
}
});
// 设置视频广告监听器
ad.setVideoAdListener(new DirichletNativeFeedAd.VideoAdListener() {
@Override
public void onVideoPrepared(DirichletNativeFeedAd ad) {
Log.d("DirichletAd", "视频准备完成");
}
@Override
public void onVideoStart(DirichletNativeFeedAd ad) {
Log.d("DirichletAd", "视频开始播放");
}
@Override
public void onVideoPause(DirichletNativeFeedAd ad) {
Log.d("DirichletAd", "视频停止播放");
}
@Override
public void onVideoError(DirichletNativeFeedAd ad, int errorCode, String message) {
Log.d("DirichletAd", "视频播放错误: " + errorCode + ", " + message);
}
});
}
自渲染信息流广告接口说明
public interface DirichletNativeFeedAd {
/**
* 获取广告应用图标 url
*/
String getIconUrl();
/**
* 设置 logo 在广告容器中的位置
*/
void setLogoLayoutParams(FrameLayout.LayoutParams params);
/**
* 获取图片 ImageInfo list(宽、高、以及 url 地址)
*/
List<ImageInfo> getImageInfoList();
/**
* 广告标题
*/
String getTitle();
/**
* 广告描述
*/
String getDescription();
/**
* 获取下载类广告的下载应用大小
*/
String getApkSize();
/**
* @return 0: unknown
* 1: 下载类广告
* 2, 3: 跳转类广告
* 4: 小程序跳转类广告
*/
int getInteractionType();
/**
* @return 1: 大图
* 2: 视频
*/
int getImageMode();
/**
* 获取广告合规信息(六要素)
*/
ComplianceInfo getComplianceInfo();
/**
* 注册可点击的 view,click/show 会在内部完成
*
* @param activity
* @param container 广告容器(DirichletAdNativeContainer)
* @param clickViews 点击区域
* @param creativeViews 创意点击区域(下载按钮等)
* @param listener 广告交互监听回调
*/
void registerViewForInteraction(Activity activity, DirichletAdNativeContainer container,
List<View> clickViews, List<View> creativeViews, AdInteractionListener listener);
/**
* 获取广告视频的视频 view
* 注意:必须在 registerViewForInteraction 前调用
*/
View getAdView();
/**
* 设置下载监听器
*/
void setDownloadListener(DirichletAppDownloadListener listener);
/**
* 设置视频广告监听器
*/
void setVideoAdListener(VideoAdListener listener);
}
资源管理与最佳实践
广告加载时机
- 激励视频:在用户可能需要奖励的场景前预加载
- 插屏广告:在关卡结束、页面切换等自然停顿点展示
- Banner 广告:在页面稳定后加载,避免影响用户体验
- 开屏广告:在应用启动时立即加载
内存管理
在 onDestroy 方法中释放广告资源:
@Override
protected void onDestroy() {
super.onDestroy();
// 释放广告对象
if (rewardVideoAd != null) {
rewardVideoAd.destroy();
rewardVideoAd = null;
}
}
常见问题
错误码说明
| 错误码 | 说明 |
|---|---|
| 200001 | 广告位无填充,参考详细msg返回 |
| 200002 | 广告数据无填充,参考详细msg返回 |
| 200010 | 广告渲染失败,参考详细msg返回 |
| 200011 | 视频播放失败,参考详细msg返回 |
| 200012 | 广告下载失败,参考详细msg返回 |
广告不展示
- 检查广告位 ID 是否正确
- 确认网络连接正常
- 验证媒体配置信息(Media ID、Media Name、Media Key)
- 查看日志中的错误信息
- 确认是否正确初始化 SDK
第三方广告平台配置问题
- 检查
AndroidManifest.xml中是否包含穿山甲和优量汇的必要配置 - 确认
@xml/gdt_file_path和@xml/csj_file_paths文件存在 - 检查资源混淆配置是否正确
广告加载失败
- 查看错误码和错误信息
- 确认广告位是否配置正确
- 检查是否有可用的广告填充
- 验证用户权限是否已授予(IMEI、位置信息等)