- 在android/app/build/gradle 添加Maven的引用
repositories {
flatDir {
dirs 'libs'
}
maven{
url'https://artifact.bytedance.com/repository/AwemeOpenSDK'
}
}
dependencies {
...
implementation(name: 'open_ad_sdk', ext: 'aar')
}
- 在 android/app/libs下 添加 open_ad_sdk.aar (文件可在官网下载)
- 在android/app/src/main/AndroidManifest.xml 添加权限控制
<<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 穿山甲广告开始 -->
<!--必要权限,解决安全风险漏洞,发送和注册广播事件需要调用带有传递权限的接口-->
<permission android:name="${applicationId}.openadsdk.permission.TT_PANGOLIN"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.openadsdk.permission.TT_PANGOLIN" />
<!--可选权限-->
<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" />
<!--demo场景用到的权限,不是必须的-->
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<!-- 穿山甲3400版本新增:建议添加“query_all_package”权限,穿山甲将通过此权限在Android R系统上判定广告对应的应用是否在用户的app上安装,避免投放错误的广告,以此提高用户的广告体验。若添加此权限,需要在您的用户隐私文档中声明! -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
- 在android/app/src/main/AndroidManifest.xml 添加provider控制
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
...
<application>
<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>
- 在android/app/src/main/res/xml目录下,新建一个xml文件file_paths,在该文件中添加如下代码
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--为了适配所有路径可以设置 path = "." -->
<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" />
<cache-path name="tt_internal_cache_download" path="Download" />
</paths>
6.在android/app/src/main/java/com/project_name目录下 新建TTAd目录,并添加以下3个文件
// android/app/src/main/java/com/project_name/TTAd/TTAdModule.java
package your_package_name;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull;
public class TTAdModule implements ReactPackage {
@Nonnull
@Override
public List<NativeModule> createNativeModules(@Nonnull ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(
new TTAdFullScreenVideoModule(reactContext)
);
}
@Nonnull
@Override
public List<ViewManager> createViewManagers(@Nonnull ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
);
}
}
// android/app/src/main/java/com/project_name/TTAd/TTAdFullScreenVideoModule.java
package your_package_name;
import android.util.Log;
import androidx.annotation.Nullable;
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.TTFullScreenVideoAd;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import javax.annotation.Nonnull;
public class TTAdFullScreenVideoModule extends ReactContextBaseJavaModule {
public static final String REACT_CLASS = "TTAdFullScreenVideo";
public static final String EVENT_AD_SHOWED = "fullScreenVideoAdShowed";
public static final String EVENT_AD_VIDEO_BAR_CLICK = "fullScreenVideoAdClick";
public static final String EVENT_AD_VIDEO_CLOSE = "fullScreenVideoAdClose";
public static final String EVENT_AD_VIDEO_COMPLETE = "fullScreenVideoComplete";
public static final String EVENT_AD_SKIPPED_VIDEO = "fullScreenVideoSkipped";
public static final String EVENT_AD_FAILED_TO_LOAD = "fullScreenVideoAdFailedToLoad";
private static final String TAG = "FullScreenVideoActivity";
private TTFullScreenVideoAd mttFullVideoAd;
public TTAdFullScreenVideoModule(@Nonnull ReactApplicationContext reactContext) {
super(reactContext);
}
@Nonnull
@Override
public String getName() {
return REACT_CLASS;
}
@ReactMethod
public void showFullScreenVideoAd(String codeId) {
try {
initFullScreenVideoAd(codeId);
Log.e("...ScreenVideoModule", codeId);
} catch (Exception e) {
Log.e("...ScreenVideoModule", e.getMessage());
}
}
private void showAd() {
getCurrentActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (mttFullVideoAd != null) {
mttFullVideoAd.showFullScreenVideoAd(getCurrentActivity(), TTAdConstant.RitScenes.GAME_GIFT_BONUS, null);
}
}
});
}
private void sendEvent(String eventName, @Nullable WritableMap params) {
getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
}
@ReactMethod
public void initFullScreenVideoAd(String codeId) {
//step1:初始化sdk
TTAdManager ttAdManager = TTAdManagerHolder.get();
//step2:(可选,强烈建议在合适的时机调用):申请部分权限,如read_phone_state,防止获取不了imei时候,下载类广告没有填充的问题。
TTAdManagerHolder.get().requestPermissionIfNecessary((MainActivity) getCurrentActivity());
//step3:创建TTAdNative对象,用于调用广告请求接口
TTAdNative mTTAdNative = ttAdManager.createAdNative((MainActivity) getCurrentActivity());
//step4:创建广告请求参数AdSlot,具体参数含义参考文档
AdSlot adSlot = new AdSlot.Builder()
.setCodeId(codeId)
.setSupportDeepLink(true)
.setImageAcceptedSize(1080, 1920)
.setOrientation(TTAdConstant.VERTICAL)//必填参数,期望视频的播放方向:TTAdConstant.HORIZONTAL 或 TTAdConstant.VERTICAL
.build();
//step5:请求广告
mTTAdNative.loadFullScreenVideoAd(adSlot, new TTAdNative.FullScreenVideoAdListener() {
@Override
public void onError(int code, String message) {
//TToast.show(getCurrentActivity(), message + "message");
WritableMap error = Arguments.createMap();
error.putInt("code", code);
error.putString("message", message);
sendEvent(EVENT_AD_FAILED_TO_LOAD, error);
}
@Override
public void onFullScreenVideoAdLoad(TTFullScreenVideoAd ad) {
mttFullVideoAd = ad;
mttFullVideoAd.setFullScreenVideoAdInteractionListener(new TTFullScreenVideoAd.FullScreenVideoAdInteractionListener() {
@Override
public void onAdShow() {
//TToast.show(getCurrentActivity(), "FullVideoAd show1");
sendEvent(EVENT_AD_SHOWED, null);
}
@Override
public void onAdVideoBarClick() {
//TToast.show(getCurrentActivity(), "FullVideoAd bar click");
sendEvent(EVENT_AD_VIDEO_BAR_CLICK, null);
}
@Override
public void onAdClose() {
//TToast.show(getCurrentActivity(), "FullVideoAd close");
sendEvent(EVENT_AD_VIDEO_CLOSE, null);
}
@Override
public void onVideoComplete() {
//TToast.show(getCurrentActivity(), "FullVideoAd complete");
sendEvent(EVENT_AD_VIDEO_COMPLETE, null);
}
@Override
public void onSkippedVideo() {
// TToast.show(getCurrentActivity(), "FullVideoAd skipped");
sendEvent(EVENT_AD_SKIPPED_VIDEO, null);
}
});
showAd();
}
@Override
public void onFullScreenVideoCached() {
// 已废弃 请使用 onRewardVideoCached(TTRewardVideoAd ad) 方法
}
@Override
public void onFullScreenVideoCached(TTFullScreenVideoAd ad) {
Log.e(TAG, "Callback --> onFullScreenVideoCached");
}
// @Override
// public void onRewardVideoCached() {
// }
});
}
}
// android/app/src/main/java/com/xiyuangeneroapp/TTAd/TTAdManagerHolder.java
package your_package_name;
import android.content.Context;
import android.util.Log;
import com.bytedance.sdk.openadsdk.TTAdConfig;
import com.bytedance.sdk.openadsdk.TTAdConstant;
import com.bytedance.sdk.openadsdk.TTAdManager;
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));
TTAdSdk.init(context, buildConfig(context), new TTAdSdk.InitCallback() {
@Override
public void success() {
// Log.i(TAG, "success: " + TTAdSdk.isInitSuccess());
}
@Override
public void fail(int code, String msg) {
// Log.i(TAG, "fail: code = " + code + " msg = " + msg);
}
});
sInit = true;
}
}
private static TTAdConfig buildConfig(Context context) {
return new TTAdConfig.Builder()
.appId("5001121")
.useTextureView(true) //使用TextureView控件播放视频,默认为SurfaceView,当有SurfaceView冲突的场景,可以使用TextureView
.appName("APP测试媒体")
.titleBarTheme(TTAdConstant.TITLE_BAR_THEME_DARK)
.allowShowNotify(true) //是否允许sdk展示通知栏提示
.debug(true) //测试阶段打开,可以通过日志排查问题,上线时去除该调用
.directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI, TTAdConstant.NETWORK_STATE_3G) //允许直接下载的网络状态集合
.supportMultiProcess(false)//是否支持多进程
//.httpStack(new MyOkStack3())//自定义网络库,demo中给出了okhttp3版本的样例,其余请自行开发或者咨询工作人员。
.build();
}
}
- 在 android/app/src/main/java/com/project_name/MainApplication.java 初始化
public class MainApplication extends Application implements ReactApplication {
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(new TTAdModule()); // 加这里
return packages;
}
@Override
public void onCreate() {
super.onCreate();
TTAdManagerHolder.init(this); // 加这里
SoLoader.init(this, /* native exopackage */ false);
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
DefaultNewArchitectureEntryPoint.load();
}
ReactNativeFlipper.initializeFlipper(this,getReactNativeHost().getReactInstanceManager());
}
}