Dirichlet Ad SDK Android 接入文档
SDK 概述
Dirichlet Ad SDK 是一款功能完善的移动广告SDK,支持多种广告形式:
- 开屏广告(Splash Ad):应用启动时展示的全屏广告
- 激励视频广告(Reward Video Ad):用户观看完 整视频后获得奖励
- Banner广告:固定位置的横幅广告
- 插屏广告(Interstitial Ad):全屏或半屏的插屏广告
- 信息流广告(Feed Ad):嵌入内容流中的原生广告
主要特性:
- 丰富的自定义配置选项
- 完善的隐私合规控制
- 多样化的广告交互回调
最低支持 Android 5.0(API level 21),编译环境为 Android Studio。
将 dirichlet_ad_4.2.4.3.aar 拷贝到游戏目录下的 src/main/libs 目录中。
在游戏目录下 build.gradle 文件中添加代码:
- Dirichlet Ad SDK 从 3.16.3.10 版本开始更新了 glide 的依赖,glide 版本从 4.0.0 更新到了 4.9.0。
- 从 SDK 4.1.0.0 版本开始,SDK 已不再依赖 RxJava,无需添加 RxJava 相关依赖(
io.reactivex.rxjava2:rxandroid和io.reactivex.rxjava2:rxjava)。
repositories{
flatDir{
dirs 'src/main/libs'
}
}
dependencies {
// ...
implementation(name: "dirichlet_ad_4.2.4.3", ext: "aar") // 广告 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
<!-- 广告 SDK 已添加的权限 -->
<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"/>
<provider
android:authorities="${applicationId}.com.tds.ad.fileprovider"
android:name="com.tapsdk.tapad.internal.TapADFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/tapad_ad_file_path"/>
</provider>
AndroidManifest 组件配置
重要:SDK内部使用了多个Activity和Provider,这些组件会自动合并到您的应用中,无需手动配置。但如果遇到合并冲突,可以参考以下配置:
点击查看完整的组件配置(仅供参考,正常情况无需手动添加)
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="your.package.name">
<!-- Android 11+ 包可见性配置 -->
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
</intent>
<package android:name="com.tencent.mm" />
</queries>
<application>
<!-- SDK内部使用的Activity(自动合并,无需手动添加) -->
<!-- 竖屏视频广告Activity -->
<activity
android:name="com.tapsdk.tapad.stub.activity.Stub_Standard_Portrait_Activity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="portrait" />
<!-- 横屏视频广告Activity -->
<activity
android:name="com.tapsdk.tapad.stub.activity.Stub_Standard_Landscape_Activity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="landscape" />
<!-- 试玩广告Activity -->
<activity
android:name="com.tapsdk.tapad.stub.activity.Stub_Playable_Portrait_Activity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="portrait" />
<activity
android:name="com.tapsdk.tapad.stub.activity.Stub_Playable_Landscape_Activity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="landscape" />
<!-- 通用广告Activity -->
<activity
android:name="com.tapsdk.tapad.stub.activity.Stub_Portrait_Activity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="sensorPortrait" />
<activity
android:name="com.tapsdk.tapad.stub.activity.Stub_Landscape_Activity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="sensorLandscape" />
<!-- 内置浏览器Activity -->
<activity
android:name="com.tapsdk.tapad.internal.ui.views.web.BrowserActivity"
android:exported="false"
android:screenOrientation="sensor" />
<!-- 应用安装/打开透明Activity -->
<activity
android:name="com.tapsdk.tapad.stub.activity.Stub_Install_or_OpenApp_Translucent_Activity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false" />
<!-- FileProvider:用于APK下载安装 -->
<provider
android:name="com.tapsdk.tapad.internal.TapADFileProvider"
android:authorities="${applicationId}.com.tds.ad.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/tapad_ad_file_path" />
</provider>
<!-- 下载Provider -->
<provider
android:name="com.tapsdk.tapad.internal.download.OkDownloadProvider"
android:authorities="${applicationId}.com.tapsdk.tapad.okdownload"
android:exported="false" />
</application>
</manifest>
注意:
- 以上组件配置会通过Gradle的Manifest合并机制自动添加到您的应用中
- 如果在构建时遇到Manifest合并冲突,可以在主应用的AndroidManifest.xml中使用
tools:replace或tools:merge来解决${applicationId}会自动替换为您应用的包名
ProGuard 混淆配置
重要:SDK 已内置 R8/ProGuard 混淆规则(通过 consumerProguardFiles 自动合并),通常无需手动添加任何配置。
如遇混淆相关问题或需要自定义配置,可参考以下规则:
-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn javax.annotation.**
-dontwarn org.conscrypt.**
-dontwarn com.tapsdk.tapad.**
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
-keepattributes JavascriptInterface
-keepclassmembers class * { @android.webkit.JavascriptInterface <methods>; }
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet); }
-keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet, int); }
-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }
-keepclassmembers class * extends com.tapsdk.tapad.protobuf.GeneratedMessageLite {
<fields>;
}
-keepnames class * extends com.tapsdk.tapad.protobuf.GeneratedMessageLite
-keepnames class * extends com.tapsdk.tapad.protobuf.GeneratedMessageLite$Builder
-keeppackagenames com.tapsdk.tapad.**
注意:
- 上述规则已包含在 SDK 的 AAR 文件中,构建时会自动应用
- 正式发布前务必测试混淆后的 APK,确保广告功能正常运行
获取广告权限
为了获取更精准的广告推荐,SDK需要获取以下权限:
- READ_PHONE_STATE:用于获取设备标识信息(如IMEI)
- ACCESS_FINE_LOCATION:用于获取地理位置信息
建议在初始化之前主动请求这些权限,以提升广告填充率和用户体验。
SDK提供了两种权限请求方式:
方式一:基础权限请求(每次调用都会弹窗)
TapAdManager.get().requestPermissionIfNecessary(activity);
方式二:带频控的权限请求(推荐)
// enableFrequencyControl: true-启用频控,false-不启用频控
// 当启用频控时,SDK会记录是否已经请求过权限,避免重复弹窗
TapAdManager.get().requestPermissionIfNecessary(activity, true);
参数说明:
context:Activity 上下文,用于弹出权限请求对话框enableFrequencyControl:是否启用频控true:SDK 会通过 SharedPreferences 记录权限请求状态,只在首次调用时弹窗false:每次调用都会检查并弹出权限请求(与无参版本相同)
推荐使用场景:
- 应用启动时使用
requestPermissionIfNecessary(activity, true),避免每次启动都弹窗 - 特定场景(如用户主动触发)使用
requestPermissionIfNecessary(activity, false)或无参版本
初始化
基本初始化
在 Application 的 onCreate() 方法中初始化SDK:
import com.tapsdk.tapad.TapAdSdk;
import com.tapsdk.tapad.TapAdConfig;
import android.app.Application;
/**
* 自定义Application类
* 注意:需要在AndroidManifest.xml中配置此Application
*/
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 构建SDK配置对象
TapAdConfig config = new TapAdConfig.Builder()
.withMediaId(YOUR_MEDIA_ID) // 必填:媒体ID(在 Dirichlet Ad 平台申请)
.withMediaName("YOUR_MEDIA_NAME") // 必填:媒体名称
.withMediaKey("YOUR_MEDIA_KEY") // 必填:媒体密钥(用于签名验证)
.enableDebug(false) // 选填:是否开启调试模式(正式版务必设置为false)
.shakeEnabled(true) // 选填:是否启用摇一摇广告交互功能,默认true开启
.build();
// 初始化 Dirichlet Ad SDK
// 注意:必须在Application的onCreate中初始化,且只需初始化一次
TapAdSdk.init(this, config);
}
}
完整配置示例
/**
* 完整的SDK初始化配置示例
* 包含所有可配置参数及详细说明
*/
TapAdConfig config = new TapAdConfig.Builder()
// ========== 基础必填参数 ==========
.withMediaId(YOUR_MEDIA_ID) // 必填:媒体ID(替换为实际值)
.withMediaName("YOUR_MEDIA_NAME") // 必填:媒体名称
.withMediaKey("YOUR_MEDIA_KEY") // 必填:媒体密钥
// ========== TapTap相关配置 ==========
.withTapClientId("YOUR_TAP_CLIENT_ID") // 选填:TapTap ClientId(如接入TapTap登录)
// ========== 功能开关 ==========
.enableDebug(false) // 选填:是否开启调试模式(正式版务必设置为false)
.shakeEnabled(true) // 选填:是否启用摇一摇广告交互功能
// ========== 隐私控制配置 ==========
.withCustomController(new TapAdCustomController() {
/**
* 是否允许SDK获取地理位置信息
* @return true-允许,false-不允许
*/
@Override
public boolean isCanUseLocation() {
return true;
}
/**
* 手动提供地理位置信息
* 当isCanUseLocation返回false时,可通过此方法提供位置
* @return TapAdLocation对象,包含经纬度和精度
*/
@Override
public TapAdLocation getTapAdLocation() {
double latitude = 39.9042; // 纬度
double longitude = 116.4074; // 经度
double accuracy = 100.0; // 精度(米)
return new TapAdLocation(latitude, longitude, accuracy);
}
/**
* 是否允许SDK获取设备状态(READ_PHONE_STATE权限)
* @return true-允许,false-不允许
*/
@Override
public boolean isCanUsePhoneState() {
return true;
}
/**
* 手动提供设备IMEI
* 当isCanUsePhoneState返回false时,可通过此方法提供IMEI
* @return IMEI字符串
*/
@Override
public String getDevImei() {
return null; // 返回null表示不提供
}
/**
* 是否允许SDK获取WiFi状态
* @return true-允许,false-不允许
*/
@Override
public boolean isCanUseWifiState() {
return true;
}
/**
* 是否允许SDK写入外部存储(用于下载APK)
* @return true-允许,false-不允许
*/
@Override
public boolean isCanUseWriteExternal() {
return true;
}
/**
* 手动提供OAID(匿名设备标识符)
* @return OAID字符串
*/
@Override
public String getDevOaid() {
return null; // 返回null让SDK自动获取
}
/**
* 是否允许SDK获取应用安装列表
* @return true-允许,false-不允许
*/
@Override
public boolean alist() {
return true;
}
/**
* 是否允许SDK获取Android ID
* @return true-允许,false-不允许
*/
@Override
public boolean isCanUseAndroidId() {
return true;
}
})
.build();
// 初始化SDK
TapAdSdk.init(this, config);
广告类型
开屏广告
开屏广告为用户在进入 App 时展示的全屏广告。开屏广告为一个 View,宽高默认为 match_parent。
竖屏开屏广告 view 要求 width = 屏幕宽,height 需要 >= 75% 屏幕高,否则会影响计费。
横屏开屏广告 view 要求 width = 屏幕宽,height 需要 = 屏幕高,否则会影响计费。
建议业务逻辑:
- 每次启动应用的时候调用 SDK 接口请求开屏广告。
- SDK 会根据一定规则从候选队列里选取一个返回给游戏,获取成功就可以展示,获取失败的话本次不展示广告。
- 建议设置3-5秒的广告加载超时,超时后直接进入应用。
- 展示前务必检查广告的有效性(
isValid())和过期时间。
获取广告
import com.tapsdk.tapad.TapAdManager;
import com.tapsdk.tapad.TapAdNative;
import com.tapsdk.tapad.TapSplashAd;
import com.tapsdk.tapad.AdRequest;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
/**
* 开屏广告加载示例
*/
public class SplashAdLoader {
private TapAdNative tapAdNative;
private TapSplashAd splashAd;
public void loadSplashAd(Context context) {
// 第一步:创建广告加载器
// 注意:每个页面建议创建独立的TapAdNative实例
tapAdNative = TapAdManager.get().createAdNative(context);
// 第二步:获取屏幕尺寸(可选,用于优化广告展示效果)
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
int screenWidth = displayMetrics.widthPixels;
int screenHeight = displayMetrics.heightPixels;
// 第三步:构建广告请求参数
AdRequest adRequest = new AdRequest.Builder()
.withSpaceId("YOUR_SPLASH_AD_SPACE_ID") // 必填:开屏广告位ID(在 Dirichlet Ad 后台获取)
.withExpressViewAcceptedSize(screenWidth, screenHeight)
// 选填:期望的广告尺寸(像素),建议传入屏幕实际宽高
.build();
// 第四步:加载开屏广告
tapAdNative.loadSplashAd(adRequest, new TapAdNative.SplashAdListener() {
/**
* 广告加载成功回调
* @param splashAd 开屏广告对象,用于后续展示
*/
@Override
public void onSplashAdLoad(TapSplashAd splashAd) {
Log.d("DirichletAD", "开屏广告加载成功");
// 保存广告对象
SplashAdLoader.this.splashAd = splashAd;
// 检查广告是否有效(是否在有效期内)
if (splashAd.isValid()) {
// 广告有效,可以展示
showSplashAd(splashAd);
} else {
// 广告已过期
Log.w("DirichletAD", "开屏广告已过期");
}
}
/**
* 广告加载失败回调
* @param code 错误码
* @param message 错误信息
*/
@Override
public void onError(int code, String message) {
Log.e("DirichletAD", "开屏广告加载失败: code=" + code + ", message=" + message);
// 根据错误码进行相应处理
switch (code) {
case 102001: // 网络异常
case 102002: // 网络超时
case 102003: // 无网络连接
// 可以提示用户检查网络或直接跳过
break;
case 103004: // 请求频繁
// 建议延迟一段时间后重试
break;
case 103002: // 无广告填充
// 正常情况,直接跳过
break;
default:
// 其他错误,建议跳过广告直接进入应用
break;
}
}
});
}
private void showSplashAd(TapSplashAd splashAd) {
// 展示广告的代码(见下文)
}
}
播放
方式一:获取View并添加到容器
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import com.tapsdk.tapad.TapSplashAd;
/**
* 展示开屏广告
* @param splashAd 已加载成功的开屏广告对象
*/
private void showSplashAd(TapSplashAd splashAd) {
// 第一步:设置广告交互监听器
splashAd.setSplashInteractionListener(new TapSplashAd.AdInteractionListener() {
/**
* 用户点击跳过按钮
* 在此进行资源清理和页面跳转
*/
@Override
public void onAdSkip() {
Log.d("DirichletAD", "用户点击跳过开屏广告");
// 销毁广告视图
splashAd.destroyView();
// 释放广告资源
splashAd.dispose();
// 跳转到主页
goToMainActivity();
}
/**
* 广告倒计时结束(自动关闭)
* 通常为3-5秒后自动触发
*/
@Override
public void onAdTimeOver() {
Log.d("DirichletAD", "开屏广告倒计时结束");
// 销毁广告视图
splashAd.destroyView();
// 释放广告资源
splashAd.dispose();
// 跳转到主页
goToMainActivity();
}
/**
* 用户点击广告(跳转到落地页)
*/
@Override
public void onAdClick() {
Log.d("DirichletAD", "用户点击开屏广告");
// 通常无需特殊处理,SDK会自动处理跳转
}
/**
* 广告开始展示
*/
@Override
public void onAdShow() {
Log.d("DirichletAD", "开屏广告开始展示");
// 可以在此记录广告展示事件
}
/**
* 广告有效曝光(满足曝光条件)
* 曝光条件通常包括:展示时长、可见面积等
*/
@Override
public void onAdValidShow() {
Log.d("DirichletAD", "开屏广告有效曝光");
// 建议在此上报广告曝光事件用于数据分析
}
});
// 第二步:获取广告View
View splashView = splashAd.getSplashView(activity);
// 第三步:从父容器中移除(如果已添加过)
// 这一步是为了避免重复添加导致的异常
if (splashView.getParent() != null) {
((ViewGroup) splashView.getParent()).removeView(splashView);
}
// 第四步:添加到布局容器
RelativeLayout container = findViewById(R.id.splash_container);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, // 宽度充满父容器
RelativeLayout.LayoutParams.MATCH_PARENT // 高度充满父容器
);
container.addView(splashView, layoutParams);
}
/**
* 跳转到主页
*/
private void goToMainActivity() {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish(); // 结束开屏页
}
方式二:直接展示到Activity
splashAd.show(activity);
方式三:展示到指定容器
ViewGroup container = findViewById(R.id.splash_container);
splashAd.show(container);
设置应用Logo(仅开屏广告支持)
开屏广告支持在左上角展示应用Logo,提升品牌识别度。
说明:Logo功能仅支持开屏广告,其他广告类型(激励视频、Banner、插屏、信息流)不支持Logo设置。
在SDK初始化时设置(推荐方式)
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 加载Logo图片
Bitmap logoBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.app_logo);
// 初始化SDK时配置Logo
TapAdConfig config = new TapAdConfig.Builder()
.withMediaId(YOUR_MEDIA_ID)
.withMediaName("YOUR_MEDIA_NAME")
.withMediaKey("YOUR_MEDIA_KEY")
.withSplashLogoBitmap(logoBitmap) // 设置开屏广告左上角Logo
.enableDebug(false)
.build();
TapAdSdk.init(this, config);
}
}
Logo显示位置:
- Logo显示在开屏广告的左上角
- 竖屏时:距离顶部 44dp(状态栏下方),距离左侧 16dp
- 横屏时:距离顶部 14dp,距离左侧 16dp
- SDK会自动处理Logo的缩放和定位
注意:
- Logo设置是可选的,不设置则不显示
- Logo功能仅适用于开屏广告,不影响其他广告类型
- Logo图片会占用内存,建议使用适当尺寸
广告生命周期管理
@Override
protected void onDestroy() {
super.onDestroy();
if (splashAd != null) {
// 销毁广告视图
splashAd.destroyView();
// 释放广告资源
splashAd.dispose();
splashAd = null;
}
}