文章目录
源码
github
Android 调试 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'
AndroidManifest 配置
添加权限
<!--必须要有的权限-->
<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" />
<!-- 如果有视频相关的广告且使用textureView播放,请务必添加,否则黑屏 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
注意:为获取更好的广告推荐效果,以及提高激励视频广告、下载类广告等填充率,建议在广告请求前,合适的时机调用 SDK 提供的方法,如在用户第一次启动您的 app 后的主界面时调用如下方法:
TTAdManager接口中的方法,context可以是Activity或Application
void requestPermissionIfNecessary(Context context);
适配 Android7.0 及以上
在 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,在该文件中添加如下代码:
<?xml version="1.0" encoding="utf-8"?>
<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" />
完整的 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.td.ttad">
<!-- 运行环境配置: 本 SDK 可运行于 Android4.0 (API Level 14) 及以上版本。 -->
<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" />
<!-- 如果有视频相关的广告且使用textureView播放,请务必添加,否则黑屏 -->
<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>
<!-- 适配 Android7.0 及以上 -->
<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>
创建 TTAdManagerHolder 用于初始化 SDK
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();
}
}
修改 MainActivity
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, "安装完成,点击下载区域打开");
}
});
}
});
}
}
运行测试 Android 工程
Android 导出 ARR
-
修改 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 版本不同,输出目录可能不一样)
Unity 接入
-
打开导出的 arr 包,把 AndroidManifest 复制一份出来,用于替换 Unity 默认的 AndroidManifest
-
将导出的 arr 和 open_ad_sdk.aar 还有 刚刚复制出来的 AndroidManifest 一起复制到 Unity 工程 Plugings/Android 目录下
-
在 Plugings/Android 目录下创建 res/xml 目录,在 res/xml 目录下,新建一个 xml 文件 file_paths,在该文件中添加如下代码:(适配 Android7.0 及以上)
<?xml version="1.0" encoding="utf-8"?> <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); } /// <summary> /// 初始化广告服务 /// </summary> public void InitBtnClick() { if (jo != null) { jo.Call("Init"); } } /// <summary> /// 加载横屏广告 /// </summary> public void HorizontalBtnClick() { if (jo != null) { jo.Call("LoadHorizontalAD"); } } /// <summary> /// 加载竖屏广告 /// </summary> public void VerticalBtnClick() { if (jo != null) { jo.Call("LoadVerticalAD"); } } /// <summary> /// 显示广告视频内容 /// </summary> public void ShowVedioBtnClick() { if (jo != null) { jo.Call("ShowVedio"); } } }
-
搭建相应界面,打包 APK,测试
Unity 插件
可直接运行官方的 Demo 进行演示。
- 导入插件
- UnionApplication.java 中初始化 appid
- 交互脚本集体使用时修改 CodeId 和 UserID