源码
github
SDK 下载,SDK 接入文档
将 SDK 压缩包内的 open_ad_sdk.aar 及 android-query-full.0.26.7.jar 复制到 Application Module/libs 文件夹。
修改 Module 里的 build.gradle 文件
repositories {
flatDir {
dirs 'libs'
}
}
compile(name: 'open_ad_sdk', ext: 'aar')
compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.6'
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
注意:为获取更好的广告推荐效果,以及提高激励视频广告、下载类广告等填充率,建议在广告请求前,合适的时机调用 SDK 提供的方法,如在用户第一次启动您的 app 后的主界面时调用如下方法:
TTAdManager接口中的方法,context可以是Activity或Application
void requestPermissionIfNecessary(Context context);
在 AndroidManifest 中添加如下代码
<provider
android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
android:authorities="${applicationId}.TTFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
provider>
在 res/xml 目录下,新建一个 xml 文件 file_paths,在该文件中添加如下代码:
<paths>
<external-path name="tt_external_root" path="." />
<external-path name="tt_external_download" path="Download" />
<external-files-path name="tt_external_files_download" path="Download" />
<files-path name="tt_internal_file_download" path="Download" />
paths>
<provider
android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
android:authorities="${applicationId}.TTMultiProvider"
android:exported="false" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.td.ttad">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="24" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
intent-filter>
activity>
<provider
android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
android:authorities="${applicationId}.TTFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
provider>
<provider
android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
android:authorities="${applicationId}.TTMultiProvider"
android:exported="false" />
application>
manifest>
import com.bytedance.sdk.openadsdk.TTAdManager;
import android.content.Context;
import com.bytedance.sdk.openadsdk.TTAdConfig;
import com.bytedance.sdk.openadsdk.TTAdConstant;
import com.bytedance.sdk.openadsdk.TTAdSdk;
/**
* 可以用一个单例来保存 TTAdManager 实例,在需要初始化 sdk 的时候调用
*/
public class TTAdManagerHolder {
private static boolean sInit;
public static TTAdManager get() {
if (!sInit) {
throw new RuntimeException("TTAdSdk is not init, please check.");
}
return TTAdSdk.getAdManager();
}
public static void init(Context context) {
doInit(context);
}
//step1:接入网盟广告sdk的初始化操作,详情见接入文档和穿山甲平台说明
private static void doInit(Context context) {
if (!sInit) {
TTAdSdk.init(context, buildConfig(context));
sInit = true;
}
}
private static TTAdConfig buildConfig(Context context) {
return new TTAdConfig.Builder()
.appId("5030830")
.useTextureView(true) //使用TextureView控件播放视频,默认为SurfaceView,当有SurfaceView冲突的场景,可以使用TextureView
.appName("接入穿山甲广告测试")
.titleBarTheme(TTAdConstant.TITLE_BAR_THEME_DARK)
.allowShowNotify(true) //是否允许sdk展示通知栏提示
.allowShowPageWhenScreenLock(true) //是否在锁屏场景支持展示广告落地页
.debug(true) //测试阶段打开,可以通过日志排查问题,上线时去除该调用
.directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI, TTAdConstant.NETWORK_STATE_3G) //允许直接下载的网络状态集合
.supportMultiProcess(false)
.build();
}
}
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.bytedance.sdk.openadsdk.AdSlot;
import com.bytedance.sdk.openadsdk.TTAdConstant;
import com.bytedance.sdk.openadsdk.TTAdManager;
import com.bytedance.sdk.openadsdk.TTAdNative;
import com.bytedance.sdk.openadsdk.TTAppDownloadListener;
import com.bytedance.sdk.openadsdk.TTRewardVideoAd;
import static com.td.ttad.R.id.btnInitSDK;
import static com.td.ttad.R.id.btnLoadHorizontalAD;
import static com.td.ttad.R.id.btnLoadVerticalAD;
import static com.td.ttad.R.id.btnShowVideo;
public class MainActivity extends AppCompatActivity {
//广告接口持有者
private TTAdNative mTTAdNative;
//视频播放持有者
private TTRewardVideoAd mttRewardVideoAd;
//是否加载完成
private boolean mHasShowDownloadActive = false;
// public Button btnInitSDK;
// public Button btnLoadHorizontalAD;
// public Button btnLoadVerticalAD;
// public Button btnShowVideo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main); // 要不然会显示 Android 的默认布局文件
TTAdManagerHolder.init(this); // Unity启动活动的时候,初始化SDK
// btnInitSDK = (Button) findViewById(R.id.btnInitSDK);
// btnInitSDK.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// Init();
// }
// });
// btnLoadHorizontalAD = (Button) findViewById(R.id.btnLoadHorizontalAD);
// btnLoadHorizontalAD.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// LoadHorizontalAD();
// }
// });
// btnLoadVerticalAD = (Button) findViewById(R.id.btnLoadVerticalAD);
// btnLoadVerticalAD.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// LoadVerticalAD();
// }
// });
// btnShowVideo = (Button) findViewById(R.id.btnShowVideo);
// btnShowVideo.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// ShowVedio();
// }
// });
}
//初始化广告配置
public void Init() {
//step1:初始化sdk
TTAdManager ttAdManager = TTAdManagerHolder.get();
//step2:(可选,强烈建议在合适的时机调用):申请部分权限,如read_phone_state,防止获取不了imei时候,下载类广告没有填充的问题。
TTAdManagerHolder.get().requestPermissionIfNecessary(this);
//step3:创建 TTAdNative 对象,用于调用广告请求接口
mTTAdNative = ttAdManager.createAdNative(getApplicationContext());
}
// 加载(缓存)横屏广告
public void LoadHorizontalAD() {
loadAd("930830162", TTAdConstant.HORIZONTAL);
}
// 加载(缓存)竖屏广告
public void LoadVerticalAD() {
loadAd("930830893", TTAdConstant.VERTICAL);
}
// 加载完成,显示广告内容
public void ShowVedio() {
//在Android的UI线程显示
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mttRewardVideoAd != null) {
//step6:在获取到广告后展示
TToast(MainActivity.this, "加载成功显示");
mttRewardVideoAd.showRewardVideoAd(MainActivity.this);
TToast(MainActivity.this, "显示调用完成");
mttRewardVideoAd = null;
} else {
TToast(MainActivity.this, "请先加载广告");
}
}
});
}
// TToast显示信息
public void TToast(final Context context, final String msg) {
//在Android的UI线程显示
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
});
}
// 配置广告配置,请求广告
private void loadAd(String codeId, int orientation) {
//step4:创建广告请求参数AdSlot,具体参数含义参考文档
AdSlot adSlot = new AdSlot.Builder()
.setCodeId(codeId)
.setSupportDeepLink(true)
.setImageAcceptedSize(1080, 1920)
.setRewardName("金币") //奖励的名称
.setRewardAmount(3) //奖励的数量
.setUserID("15592")//用户id,必传参数
.setMediaExtra("media_extra") //附加参数,可选
.setOrientation(orientation) //必填参数,期望视频的播放方向:TTAdConstant.HORIZONTAL 或 TTAdConstant.VERTICAL
.build();
//step5:请求广告
mTTAdNative.loadRewardVideoAd(adSlot, new TTAdNative.RewardVideoAdListener() {
@Override
public void onError(int code, String message) {
TToast(MainActivity.this, message);
}
//视频广告加载后,视频资源缓存到本地的回调,在此回调后,播放本地视频,流畅不阻塞。
@Override
public void onRewardVideoCached() {
TToast(MainActivity.this, "rewardVideoAd video cached");
}
//视频广告的素材加载完毕,比如视频url等,在此回调后,可以播放在线视频,网络不好可能出现加载缓冲,影响体验。
@Override
public void onRewardVideoAdLoad(TTRewardVideoAd ad) {
TToast(MainActivity.this, "rewardVideoAd loaded");
mttRewardVideoAd = ad;
// mttRewardVideoAd.setShowDownLoadBar(false);
mttRewardVideoAd.setRewardAdInteractionListener(new TTRewardVideoAd.RewardAdInteractionListener() {
@Override
public void onAdShow() {
TToast(MainActivity.this, "rewardVideoAd show");
}
@Override
public void onAdVideoBarClick() {
TToast(MainActivity.this, "rewardVideoAd bar click");
}
@Override
public void onAdClose() {
TToast(MainActivity.this, "rewardVideoAd close");
}
//视频播放完成回调
@Override
public void onVideoComplete() {
TToast(MainActivity.this, "rewardVideoAd complete");
}
@Override
public void onVideoError() {
TToast(MainActivity.this, "rewardVideoAd error");
}
//视频播放完成后,奖励验证回调,rewardVerify:是否有效,rewardAmount:奖励梳理,rewardName:奖励名称
@Override
public void onRewardVerify(boolean rewardVerify, int rewardAmount, String rewardName) {
TToast(MainActivity.this, "verify:" + rewardVerify + " amount:" + rewardAmount +
" name:" + rewardName);
}
});
mttRewardVideoAd.setDownloadListener(new TTAppDownloadListener() {
@Override
public void onIdle() {
mHasShowDownloadActive = false;
}
@Override
public void onDownloadActive(long totalBytes, long currBytes, String fileName, String appName) {
if (!mHasShowDownloadActive) {
mHasShowDownloadActive = true;
TToast(MainActivity.this, "下载中,点击下载区域暂停");
}
}
@Override
public void onDownloadPaused(long totalBytes, long currBytes, String fileName, String appName) {
TToast(MainActivity.this, "下载暂停,点击下载区域继续");
}
@Override
public void onDownloadFailed(long totalBytes, long currBytes, String fileName, String appName) {
TToast(MainActivity.this, "下载失败,点击下载区域重新下载");
}
@Override
public void onDownloadFinished(long totalBytes, String fileName, String appName) {
TToast(MainActivity.this, "下载完成,点击下载区域重新下载");
}
@Override
public void onInstalled(String fileName, String appName) {
TToast(MainActivity.this, "安装完成,点击下载区域打开");
}
});
}
});
}
}
修改 MainActivity 继承 UnityPlayerActivity
public class MainActivity extends UnityPlayerActivity { ... }
修改 Module 下的 build.gradle 文件
//apply plugin: 'com.android.application'
apply plugin: 'com.android.library' // 不生成 apk,生成 jar/aar 包
android {
defaultConfig {
// applicationId "com.td.sdkaccess" 注释这一行
...
}
...
// 方便操作,复制 jar 到指定位置
task makeJar(type:Copy){
delete 'build/libs/sdk.jar'
from('build/intermediates/bundles/release/')
into('build/libs/')
include('classes.jar')
rename('classes.jar','sdk.jar')
}
Build -> Rebuild Project
到相应目录查看 app->build->outputs->aar,(android studio 版本不同,输出目录可能不一样)
打开导出的 arr 包,把 AndroidManifest 复制一份出来,用于替换 Unity 默认的 AndroidManifest
将导出的 arr 和 open_ad_sdk.aar 还有 刚刚复制出来的 AndroidManifest 一起复制到 Unity 工程 Plugings/Android 目录下
在 Plugings/Android 目录下创建 res/xml 目录,在 res/xml 目录下,新建一个 xml 文件 file_paths,在该文件中添加如下代码:(适配 Android7.0 及以上)
<paths>
<external-path name="tt_external_root" path="." />
<external-path name="tt_external_download" path="Download" />
<external-files-path name="tt_external_files_download" path="Download" />
<files-path name="tt_internal_file_download" path="Download" />
paths>
新建脚本 TTAdHolder,并挂载到场景的 GameObject 身上,内容如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TTAdHolder : MonoBehaviour {
private AndroidJavaClass jc;
private AndroidJavaObject jo;
public Button btnInit;
public Button btnLoadHorizontalAD;
public Button btnLoadVerticalAD;
public Button btnShowAD;
public void Awake() {
#if UNITY_ANDROID &&!UNITY_EDITOR
// 获取 Unity 的 MainActivity 的固定写法
jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
#endif
btnInit.onClick.AddListener(InitBtnClick);
btnLoadHorizontalAD.onClick.AddListener(HorizontalBtnClick);
btnLoadVerticalAD.onClick.AddListener(VerticalBtnClick);
btnShowAD.onClick.AddListener(ShowVedioBtnClick);
}
///
/// 初始化广告服务
///
public void InitBtnClick() {
if (jo != null) {
jo.Call("Init");
}
}
///
/// 加载横屏广告
///
public void HorizontalBtnClick() {
if (jo != null) {
jo.Call("LoadHorizontalAD");
}
}
///
/// 加载竖屏广告
///
public void VerticalBtnClick() {
if (jo != null) {
jo.Call("LoadVerticalAD");
}
}
///
/// 显示广告视频内容
///
public void ShowVedioBtnClick() {
if (jo != null) {
jo.Call("ShowVedio");
}
}
}
搭建相应界面,打包 APK,测试
头条网盟SDK Unity插件——接入说明文档
可直接运行官方的 Demo 进行演示。