react-native Android集成穿山甲

2023-09-04 18:49阅读 0
  1. 在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')
}
  1. 在 android/app/libs下 添加 open_ad_sdk.aar (文件可在官网下载)
  2. 在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"/>

    


  1. 在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>

  1. 在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();
    }
}
  1. 在 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());
  }
}
标签
标签
标签