CososCreator (Android)-AppLovin MAX 广告聚合平台接入+Firebase统计

2023-11-05

CososCreator 2.4.4

Android Studio :4.2.1

接入SDK有:接max聚合及中介平台(Admob,FB, applovin,pangle,mintegral,vungle,unity),和Firebase 统计

1、构建Android工程

 2、升级gradle版本

升级完后可能出现如下问题:

a)A problem occurred evaluating project ':game'.
> Plugin with id 'com.android.feature' not found. 

解决参考链接: 
Cocos Creator Android原生项目升级gradle版本 - Creator 2.x - Cocos中文社区gradle 版本原来版本 :4.10.3(插件3.2.0) 升级后版本: 5.6.4(插件3.6.3) gradle路径:jsb-default/frameworks/runtime-src/proj.android-studi…https://forum.cocos.org/t/topic/103837

 

b)Execution failed for task ':food:mergeDebugAssets'.
> Could not copy file 'F:\Hopemobi\food_B\build\jsb-link\assets\internal' to 'F:\Hopemobi\food_B\build\jsb-link\frameworks\runtime-src\proj.android-studio\app\task ':food:mergeDebugAssets' property 'outputDir'\assets\internal'.
   > Failed to create parent directory 'F:\Hopemobi\food_B\build\jsb-link\frameworks\runtime-src\proj.android-studio\app\task ':food:mergeDebugAssets' property 'outputDir'' when creating directory 'F:\Hopemobi\food_B\build\jsb-link\frameworks\runtime-src\proj.android-studio\app\task ':food:mergeDebugAssets' property 'outputDir'\assets\internal'

app/build.gradle(资源复制丢失)

原因:构建失败

路径:jsb-default/frameworks/runtime-src/proj.android-studio/app/build.gradle

android.applicationVariants.all { variant ->
    // delete previous files first
    delete "${buildDir}/intermediates/merged_assets/${variant.dirName}"
       //修改 报警错误 API 'variant.getMergeAssets()' is obsolete and has been replaced with 'variant.getMergeAssetsProvider()'.It will be removed at the end of 2019.                          
//  variant.mergeAssets.doLast {
    variant.mergeAssetsProvider.get().doLast{
        def sourceDir = "${buildDir}/../../../../.."

        copy {
            from "${sourceDir}/assets"
            into outputDir.dir("assets")
            into outputDir.dir("assets")
        }

        copy {
            from "${sourceDir}/src"
            into "${outputDir}/src"
            into outputDir.dir("src")
        }

        copy {
            from "${sourceDir}/jsb-adapter"
            into "${outputDir}/jsb-adapter"
            into outputDir.dir("jsb-adapter")
        }

        copy {
            from "${sourceDir}/main.js"
            from "${sourceDir}/project.json"
            into outputDir
        }
    }
}

c) 将项目选择为游戏项目,运行

 

 3、AppLovin Max聚合接入(具体接入根据官方来,本文提供一些接入问题)

官方文档:

 MAX Mediation Documentationhttps://dash.applovin.com/documentation/mediation/android/getting-started/integration添加到应用程序级 build.gradle中加入:

repositories {
    google()
    mavenCentral()
    ⋮
}
dependencies {
    implementation 'com.applovin:applovin-sdk:+'

}
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}
注意: AppLovin SDK 要求您将 minSdkVersion 设置为 16 或以上。

 添加 SDK 密钥:<meta-data>元素到你的AndroidManifest.xml

<meta-data android:name="applovin.sdk.key"
           android:value="YOUR_SDK_KEY_HERE"/>

添加到应用程序级 build.gradle 文件

apply plugin: 'applovin-quality-service'
applovin {
       apiKey "YOUR_AD_REVIEW_KEY_HERE"
}

添加到根级 build.gradle 文件

buildscript {
    repositories {
        maven { url 'https://artifacts.applovin.com/android' }
    }
    dependencies {
        classpath "com.applovin.quality:AppLovinQualityServiceGradlePlugin:+"
    }
}

d)This project uses AndroidX dependencies, but the android.useAndroidX property is not enabled

This project uses AndroidX dependencies, but the android.useAndroidX property is not enabled的解决_7DO的博客-CSDN博客

gradle.properties中加入:

android.useAndroidX=true
android.enableJetifier=true

e)Execution failed for task ':food:processReleaseMainManifest'.
> Manifest merger failed : uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [com.google.android.gms:play-services-ads:21.3.0] 

PROP_MIN_SDK_VERSION=21

f)Manifest merger failed : Apps targeting Android 12 and higher are required to specify an explicit v

Manifest merger failed : Apps targeting Android 12 and higher are required to specify an explicit v_lplj717的博客-CSDN博客

g)Expiring Daemon because JVM heap space is exhausted

Expiring Daemon because JVM heap space is exhausted_auccy的博客-CSDN博客_expiring daemon

在 gradle.properties 文件中添加

org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=512m

f)Could not determine the dependencies of task ':food:lintVitalRelease'.
> Could not resolve all artifacts for configuration ':food:debugCompileClasspath'.
   > Could not find com.pangle.global:ads-sdk:4.8.1.0.

buildscript和allprojects和subprojects的区别.Android Studio_厚积而薄发ing的博客-CSDN博客_android subprojects

在buildscript,allprojects 中都添加上 

 

 最终根级 build.gradle 文件

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

    repositories {
        google()
        jcenter()
        maven { url 'https://artifacts.applovin.com/android' }
        maven { url "https://artifact.bytedance.com/repository/pangle" }
        maven { url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.2.1'
        classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:+'
        classpath 'com.google.gms:google-services:4.3.14'  //firebase

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        flatDir {
            dirs 'libs'
        }

        maven { url "https://artifact.bytedance.com/repository/pangle" }
        maven { url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

  最终根级 build.gradle 文件

import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'com.android.application'
apply plugin: 'applovin-quality-service'
apply plugin: 'com.google.gms.google-services'

applovin {
    // NOTE: DO NOT CHANGE - this is NOT your AppLovin MAX SDK key - this is a derived key.
    apiKey 'e8dPgaJuOF6-3xeoEizRgzB34eU-yLeAmiXTMhPFLstzUTpTF20SaWC8y3n0wbxVCXoHhdet1wyp9-MUBs__iy'
}

android {
    compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
    buildToolsVersion '30.0.2'

    defaultConfig {
        applicationId "com.starqbaby.FastFood"
        minSdkVersion PROP_MIN_SDK_VERSION
        targetSdkVersion PROP_TARGET_SDK_VERSION
        versionCode 12
        versionName "1.0.12"

        externalNativeBuild {
            ndkBuild {
                if (!project.hasProperty("PROP_NDK_MODE") || PROP_NDK_MODE.compareTo('none') != 0) {
                    // skip the NDK Build step if PROP_NDK_MODE is none
                    targets 'cocos2djs'
                    arguments 'NDK_TOOLCHAIN_VERSION=clang'

                    def module_paths = [project.file("D:/CocosDashboard_1.0.14/resources/.editors/Creator/2.4.4/resources/cocos2d-x"),
                                        project.file("D:/CocosDashboard_1.0.14/resources/.editors/Creator/2.4.4/resources/cocos2d-x/cocos"),
                                        project.file("D:/CocosDashboard_1.0.14/resources/.editors/Creator/2.4.4/resources/cocos2d-x/external")]
                    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                        arguments 'NDK_MODULE_PATH=' + module_paths.join(";")
                    }
                    else {
                        arguments 'NDK_MODULE_PATH=' + module_paths.join(':')
                    }

                    arguments '-j' + Runtime.runtime.availableProcessors()
                    abiFilters.addAll(PROP_APP_ABI.split(':').collect{it as String})
                }
            }
        }
    }

    sourceSets.main {
        java.srcDirs "../src", "src"
        res.srcDirs "../res", 'res'
        jniLibs.srcDirs "../libs", 'libs'
        manifest.srcFile "AndroidManifest.xml"
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    externalNativeBuild {
        ndkBuild {
            if (!project.hasProperty("PROP_NDK_MODE") || PROP_NDK_MODE.compareTo('none') != 0) {
                // skip the NDK Build step if PROP_NDK_MODE is none
                path "jni/Android.mk"
            }
        }
    }

    signingConfigs {

       release {
            if (project.hasProperty("RELEASE_STORE_FILE")) {
                storeFile file(RELEASE_STORE_FILE)
                storePassword RELEASE_STORE_PASSWORD
                keyAlias RELEASE_KEY_ALIAS
                keyPassword RELEASE_KEY_PASSWORD
            }
        }
    }

    buildTypes {
        release {
            debuggable false
            jniDebuggable false
            renderscriptDebuggable false
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            if (project.hasProperty("RELEASE_STORE_FILE")) {
                signingConfig signingConfigs.release
            }

            externalNativeBuild {
                ndkBuild {
                    arguments 'NDK_DEBUG=0'
                }
            }
        }

        debug {
            debuggable true
            jniDebuggable true
            renderscriptDebuggable true
            externalNativeBuild {
                ndkBuild {
                    arguments 'NDK_DEBUG=1'
                }
            }
        }
    }
}

android.applicationVariants.all { variant ->
    // delete previous files first
    delete "${buildDir}/intermediates/merged_assets/${variant.dirName}"
    //修改 报警错误 API 'variant.getMergeAssets()' is obsolete and has been replaced with 'variant.getMergeAssetsProvider()'.It will be removed at the end of 2019.
//  variant.mergeAssets.doLast {
    variant.mergeAssetsProvider.get().doLast{
        def sourceDir = "${buildDir}/../../../../.."

        copy {
            from "${sourceDir}/assets"
            into outputDir.dir("assets")
            into outputDir.dir("assets")
        }

        copy {
            from "${sourceDir}/src"
            into "${outputDir}/src"
            into outputDir.dir("src")
        }

        copy {
            from "${sourceDir}/jsb-adapter"
            into "${outputDir}/jsb-adapter"
            into outputDir.dir("jsb-adapter")
        }

        copy {
            from "${sourceDir}/main.js"
            from "${sourceDir}/project.json"
            into outputDir
        }
    }
}

dependencies {
    implementation fileTree(dir: '../libs', include: ['*.jar','*.aar'])
    implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
    implementation fileTree(dir: "D:/CocosDashboard_1.0.14/resources/.editors/Creator/2.4.4/resources/cocos2d-x/cocos/platform/android/java/libs", include: ['*.jar'])
    implementation project(':libcocos2dx')

    implementation 'com.applovin:applovin-sdk:+'
    // Import the Firebase BoM
    implementation platform('com.google.firebase:firebase-bom:31.1.1')
    // Declare the dependency for the Firebase SDK for Google Analytics
    implementation 'com.google.firebase:firebase-analytics'

    //其他中介广告源
    //Admob
    implementation 'com.applovin.mediation:google-adapter:+'
    //FB
    implementation 'com.applovin.mediation:facebook-adapter:+'

    //vungle
    implementation 'com.applovin.mediation:vungle-adapter:+'
    //unity
    implementation 'com.applovin.mediation:unityads-adapter:+'

    //pangle
    implementation 'com.applovin.mediation:bytedance-adapter:+'
    //mintegral
    implementation 'com.applovin.mediation:mintegral-adapter:+'
    implementation 'androidx.recyclerview:recyclerview:1.1.0'

}

 AdsBanner.java

package org.cocos2dx.javascript.ads;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import com.applovin.mediation.MaxAd;
import com.applovin.mediation.MaxAdViewAdListener;
import com.applovin.mediation.MaxError;
import com.applovin.mediation.ads.MaxAdView;
import com.starqbaby.FastFood.R;

import org.cocos2dx.javascript.AdManage;
import org.cocos2dx.javascript.AppActivity;

public class AdsBanner {

    private Context mainActive = null;
    private ViewGroup rootView;
    private MaxAdView mAdView;
    private String adPos;
    private int screenWidth;
    //-----------类型常量-------------
    private static String BANNER_TYPE = "0";
    //获得广告位id
    private static String AD_Banner_ID;

    public void init(Context context,int wid){
        this.mainActive = context;
        this.screenWidth = wid;
        AD_Banner_ID = AdManage.getInstance().getUnitID(BANNER_TYPE);
    }

    /*
       加载banner广告
     */
    public void loadBannerAd() {
        //请求banner
        AdManage.getInstance().FAEventSuccess("Mobi_40101",AD_Banner_ID,BANNER_TYPE);

        mAdView = new MaxAdView(AD_Banner_ID,this.mainActive );

        // Stretch to the width of the screen for banners to be fully functional
        int width = ViewGroup.LayoutParams.WRAP_CONTENT;
        // Banner height on phones and tablets is 50 and 90, respectively
        int heightPx = this.mainActive.getResources().getDimensionPixelSize( R.dimen.banner_height );
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( width, heightPx ) ;
        params.gravity=Gravity.TOP;
        //params.leftMargin = this.screenWidth /2;

        Log.d(AdManage.getInstance().TAG, "screenWidth"+this.screenWidth);

        mAdView.setLayoutParams(params);
        //Set background or background color for banners to be fully functional
        //adView.setBackgroundColor( ... );

        rootView= (ViewGroup)((Activity) this.mainActive).findViewById(android.R.id.content);
        rootView.addView( mAdView );
        mAdView.setVisibility(View.VISIBLE);

        // Load the ad
        mAdView.loadAd();
        //banner监听
        mAdView.setListener(new MaxAdViewAdListener() {
            // MAX Ad Listener
            @Override
            public void onAdLoaded(final MaxAd maxAd)
            {
                Log.d(AdManage.getInstance().TAG, "onAdLoaded: (banner)");
                //successFAEvent("loadBannerAd");
                AdManage.getInstance().FAEventSuccess("Mobi_40201",AD_Banner_ID,BANNER_TYPE);
            }

            @Override
            public void onAdLoadFailed(final String adUnitId, final MaxError error)
            {
                Log.d(AdManage.getInstance().TAG, "onAdFailedToLoad: (banner)"+error);
                String errorMessage = error.getMessage();
                //加载错误事件
                int errorCode = error.getCode();
                //failFAEvent(errorCode,"banner");
                //-----
                //广告填充失败
                AdManage.getInstance().FAEventFail("Mobi_40201",AD_Banner_ID,BANNER_TYPE,String.valueOf(errorCode),errorMessage);

            }

            @Override
            public void onAdDisplayFailed(final MaxAd maxAd, final MaxError error) {}

            @Override
            public void onAdClicked(final MaxAd maxAd)
            {
                //广告点击
                AdManage.getInstance().FAEventSuccess("Mobi_40401",AD_Banner_ID,BANNER_TYPE);
            }

            @Override
            public void onAdExpanded(final MaxAd maxAd) {}

            @Override
            public void onAdCollapsed(final MaxAd maxAd) {}

            @Override
            public void onAdDisplayed(final MaxAd maxAd) { /* DO NOT USE - THIS IS RESERVED FOR FULLSCREEN ADS ONLY AND WILL BE REMOVED IN A FUTURE SDK RELEASE */ }

            @Override
            public void onAdHidden(final MaxAd maxAd) { /* DO NOT USE - THIS IS RESERVED FOR FULLSCREEN ADS ONLY AND WILL BE REMOVED IN A FUTURE SDK RELEASE */ }
        });
    }

    /*
       banner广告
     */
    public void showBannerAd(String pos){
        AppActivity mActivity = (AppActivity)this.mainActive;
        this.adPos = pos;
        int mWidth = this.screenWidth;
        //一定要确保在UI线程操作
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Log.d(AdManage.getInstance().TAG, "showBannerAd: adPos "+adPos);

                FrameLayout.LayoutParams  params=(FrameLayout.LayoutParams )mAdView.getLayoutParams();
                if(adPos.equals("top")){
                    params.gravity=Gravity.TOP;
                    params.leftMargin = 0;
                }else if(adPos.equals("top-left")){
                    params.gravity=Gravity.TOP;
                    params.leftMargin = -mWidth /2;
                }else if(adPos.equals("bottom")){
                    params.gravity=Gravity.BOTTOM;
                    params.leftMargin = 0;
                }else if(adPos.equals("bottom-left")){
                    params.gravity=Gravity.BOTTOM;
                    params.leftMargin = -mWidth /2;
                }
                mAdView.setLayoutParams(params);
                mAdView.setVisibility(View.VISIBLE);

            }
        });
    }

    /*
       隐藏 banner广告
     */
    public void hideBannerAd(){

        //有用接口,先注释,取消隐藏banner
        AppActivity mActivity = (AppActivity)this.mainActive;
        //一定要确保在UI线程操作
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Log.d(AdManage.getInstance().TAG, "hideBannerAd");
                mAdView.setVisibility(View.INVISIBLE);
            }
        });
    }
}

AdsInterstitial.java

package org.cocos2dx.javascript.ads;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;


import com.applovin.mediation.MaxAd;
import com.applovin.mediation.MaxAdListener;
import com.applovin.mediation.MaxError;
import com.applovin.mediation.ads.MaxInterstitialAd;

import org.cocos2dx.javascript.AdManage;
import org.cocos2dx.javascript.AppActivity;
import org.cocos2dx.lib.Cocos2dxJavascriptJavaBridge;

import java.util.concurrent.TimeUnit;

public class AdsInterstitial implements MaxAdListener {

    private static String INTERSTITIAL_TYPE = "1"; //类型常量
    private  static String AD_INTERSTITIAL_ID;//正式插屏


    private  static MaxInterstitialAd interstitialAd;

    private int insUnitIdIdex = 0;
    private int insReLoadTime = 1; //插屏加载失败时,允许重新加载几次插屏
    private int curInsReloadTime = 0; //当前插屏重新加载次数

    private Context mainActive = null;


    public void init(Context context){
        this.mainActive = context;
        AD_INTERSTITIAL_ID = AdManage.getInstance().getUnitID(INTERSTITIAL_TYPE);
    }

    private  int retryAttempt;
    public void loadInterstitalAd(){
        AppActivity mActivity = (AppActivity)this.mainActive;
        AdsInterstitial mUser=this;
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Log.d(AdManage.getInstance().TAG, "loadInterstitalAd....: "+AdsInterstitial.AD_INTERSTITIAL_ID);
                //successFAEvent("LoadInterstitalAd");
                //插屏广告请求
                AdManage.getInstance().FAEventSuccess("Mobi_40101",AdsInterstitial.AD_INTERSTITIAL_ID,INTERSTITIAL_TYPE);

                MaxInterstitialAd interstitialAd = new MaxInterstitialAd( AdsInterstitial.AD_INTERSTITIAL_ID, mActivity );
                // Load the first ad
                AdsInterstitial.interstitialAd=interstitialAd;
                interstitialAd.setListener(mUser);
                interstitialAd.loadAd();

            }
        });
    }
    public void showInterstitialAd() {
        // Show the ad if it's ready. Otherwise toast and restart the game.
        Log.d(AdManage.getInstance().TAG, "showInterstitial: ");
        AppActivity mActivity = (AppActivity)this.mainActive;
        //一定要确保在UI线程操作
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (AdsInterstitial.interstitialAd != null && interstitialAd.isReady()) {
                    interstitialAd.showAd();
                } else {
                    Toast.makeText((Activity) mActivity, "Ad did not load", Toast.LENGTH_SHORT).show();
                }

                AdManage.getInstance().FAEventSuccess("Mobi_40301", AdsInterstitial.AD_INTERSTITIAL_ID, INTERSTITIAL_TYPE);
            }
        });
    }

    @Override
    public void onAdLoaded(MaxAd ad) {
        Log.i(AdManage.getInstance().TAG, "onAdLoaded(AdsInterstitial)");
        //加载插屏广告成功
        AdManage.getInstance().FAEventSuccess("Mobi_40201",AdsInterstitial.AD_INTERSTITIAL_ID,INTERSTITIAL_TYPE);
        retryAttempt = 0;
    }

    @Override
    public void onAdLoadFailed(String adUnitId, MaxError error) {
        String error1 =String.format("code: %d, message: %s",error.getCode(), error.getMessage());
        Log.d(AdManage.getInstance().TAG, "AdsInterstitial Failed : " + error1);

        String errorMessage = error.getMessage();
        //加载错误事件
        int errorCode = error.getCode();
        //failFAEvent(errorCode,"InterstitalAd");
        //-----
        //广告填充失败
        AdManage.getInstance().FAEventFail("Mobi_40201",AdsInterstitial.AD_INTERSTITIAL_ID,INTERSTITIAL_TYPE,String.valueOf(errorCode),errorMessage);

        //Toast.makeText((Activity) mActivity, "onAdFailedToLoad() with error: " + error1, Toast.LENGTH_SHORT).show();

        retryAttempt++;
        long delayMillis = TimeUnit.SECONDS.toMillis( (long) Math.pow( 2, Math.min( 6, retryAttempt ) ) );

        new Handler().postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                interstitialAd.loadAd();
            }
        }, delayMillis );
    }

    @Override
    public void onAdDisplayFailed(MaxAd ad, MaxError error) {
        Log.d(AdManage.getInstance().TAG, "onAdDisplayFailed");
        interstitialAd.loadAd();
    }

    @Override
    public void onAdDisplayed(MaxAd ad) {
        Log.d(AdManage.getInstance().TAG, "onAdDisplayed");
    }

    @Override
    public void onAdClicked(MaxAd ad) {
        Log.d(AdManage.getInstance().TAG, "onAdClicked");
    }

    @Override
    public void onAdHidden(MaxAd ad) {
        Log.d(AdManage.getInstance().TAG, "onAdHidden");
        interstitialAd.loadAd();

        AppActivity app = (AppActivity) this.mainActive;
        app.runOnGLThread(new Runnable() {
            @Override
            public void run() {
                Cocos2dxJavascriptJavaBridge.evalString("window.PlatformApi.getInterstitalHidden()");
                Log.d(AdManage.getInstance().TAG, "AdsInterstitial call onAdHidden");
            }
        });
    }
}

AdsRewarded.java

package org.cocos2dx.javascript.ads;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.applovin.mediation.MaxAd;
import com.applovin.mediation.MaxError;
import com.applovin.mediation.MaxReward;
import com.applovin.mediation.MaxRewardedAdListener;
import com.applovin.mediation.ads.MaxRewardedAd;

import org.cocos2dx.javascript.AdManage;
import org.cocos2dx.javascript.AppActivity;
import org.cocos2dx.lib.Cocos2dxJavascriptJavaBridge;

import java.util.concurrent.TimeUnit;

public class AdsRewarded {

    private Context mainActive = null;
    private static MaxRewardedAd mRewardedAd;
    private static String REWARDED_TYPE = "8";  //类型常量
    private static  String AD_VIDEO_ID;//激励视频广告ID(正式)

    public void init(Context context){
        this.mainActive = context;
        AD_VIDEO_ID = AdManage.getInstance().getUnitID(REWARDED_TYPE);
    }

    private static int retryAttempt;

    public void initVideoAd(){
        AppActivity mActivity = (AppActivity) this.mainActive;
        //一定要确保在UI线程操作
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {

                AdManage.getInstance().FAEventSuccess("Mobi_40101",AdsRewarded.AD_VIDEO_ID,REWARDED_TYPE);

                MaxRewardedAd rewardedAd = MaxRewardedAd.getInstance( AdsRewarded.AD_VIDEO_ID,mActivity );
                rewardedAd.setListener(new MaxRewardedAdListener() {
                    @Override
                    public void onAdLoaded(MaxAd ad) {
                        Log.d(AdManage.getInstance().TAG, "onAdLoaded.(AdsRewarded)");
                        AdManage.getInstance().FAEventSuccess("Mobi_40201",AdsRewarded.AD_VIDEO_ID,REWARDED_TYPE);
                        AdsRewarded.retryAttempt=0;
                    }

                    @Override
                    public void onAdLoadFailed(String adUnitId, MaxError error) {
                        String error1 =String.format("code: %d, message: %s",error.getCode(), error.getMessage());
                        Log.d(AdManage.getInstance().TAG, "AdsInterstitial Failed : " + error1);

                        String errorMessage = error.getMessage();
                        int errorCode = error.getCode();

                        AdManage.getInstance().FAEventFail("Mobi_40202",AdsRewarded.AD_VIDEO_ID,REWARDED_TYPE,String.valueOf(errorCode),errorMessage);

                        AdsRewarded.retryAttempt++;
                        long delayMillis = TimeUnit.SECONDS.toMillis( (long) Math.pow( 2, Math.min( 6, retryAttempt ) ) );

                        new Handler().postDelayed(new Runnable()
                        {
                            @Override
                            public void run()
                            {
                                AdsRewarded.mRewardedAd.loadAd();
                            }
                        }, delayMillis );
                    }

                    @Override
                    public void onAdDisplayFailed(MaxAd ad, MaxError error) {
                        AdsRewarded.mRewardedAd.loadAd();
                    }

                    @Override
                    public void onAdClicked(MaxAd ad) {

                    }
                    @Override
                    public void onAdDisplayed(MaxAd ad) {
                    }

                    @Override
                    public void onAdHidden(MaxAd ad) {
                        AdsRewarded.mRewardedAd.loadAd();

                        AppActivity app = mActivity;
                        app.runOnGLThread(new Runnable() {
                            @Override
                            public void run() {
                                Cocos2dxJavascriptJavaBridge.evalString("window.PlatformApi.getVideoHidden()");
                                Log.d(AdManage.getInstance().TAG, "AdsRewarded call onAdHidden");
                            }
                        });
                    }

                    @Override
                    public void onRewardedVideoStarted(MaxAd ad) {

                    }

                    @Override
                    public void onRewardedVideoCompleted(MaxAd ad) {

                    }

                    @Override
                    public void onUserRewarded(MaxAd ad, MaxReward reward) {
                        Log.d(AdManage.getInstance().TAG, "The user earned the reward.");
                        int rewardAmount = reward.getAmount();
                        String rewardType = reward.getLabel();
                        Log.d(AdManage.getInstance().TAG, "call before");
                        AppActivity app = mActivity;
                        app.runOnGLThread(new Runnable() {
                            @Override
                            public void run() {
                                Cocos2dxJavascriptJavaBridge.evalString("window.PlatformApi.getVideoReward()");
                                Log.d(AdManage.getInstance().TAG, "call Rewarded");
                            }
                        });
                        //successFAEvent("EarnedReward");
                        AdManage.getInstance().FAEventSuccess("Mobi_40301",AdsRewarded.AD_VIDEO_ID,REWARDED_TYPE);
                    }

                });

                AdsRewarded.mRewardedAd = rewardedAd;
                rewardedAd.loadAd();

            }
        });
    }

    //展示广告
    public void showRewardVideoAd(){
        AppActivity mActivity = (AppActivity) this.mainActive;

        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (AdsRewarded.mRewardedAd != null&&AdsRewarded.mRewardedAd.isReady()) {
                    AdsRewarded.mRewardedAd.showAd();
                } else {
                    Log.d(AdManage.getInstance().TAG, "The rewarded ad wasn't ready yet.");
                    Toast.makeText((Activity) mActivity, "Ad did not load", Toast.LENGTH_SHORT).show();
                }
            }
        });

    }

}

AdManage.java(广告管理) 

package org.cocos2dx.javascript;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.applovin.mediation.MaxAd;
import com.applovin.mediation.MaxAdListener;
import com.applovin.mediation.MaxAdViewAdListener;
import com.applovin.mediation.MaxError;
import com.applovin.mediation.MaxReward;
import com.applovin.mediation.MaxRewardedAdListener;
import com.applovin.mediation.ads.MaxAdView;
import com.applovin.mediation.ads.MaxInterstitialAd;
import com.applovin.mediation.ads.MaxRewardedAd;
import com.applovin.sdk.AppLovinSdk;
import com.applovin.sdk.AppLovinSdkConfiguration;

import org.cocos2dx.javascript.ads.AdsBanner;
import org.cocos2dx.javascript.ads.AdsInterstitial;
import org.cocos2dx.javascript.ads.AdsRewarded;
import org.cocos2dx.lib.Cocos2dxJavascriptJavaBridge;

import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.RequestConfiguration;
import static com.google.android.gms.ads.RequestConfiguration.MAX_AD_CONTENT_RATING_G;
import static com.google.android.gms.ads.RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_TRUE;


public class AdManage {

    private static final String AD_BANNER_UNIT_ID = "id";//横幅广告ID
    private static final String AD_UNIT_ID = "id"; //插页广告       
    private static final String AD_VIDEO_ID = "id";//激励视频广告ID  


    private Context mainActive = null;
    private static AdManage mInstace = null;

    private MaxAdView adView;
    private LinearLayout bannerLayout;
    private String adPos;

    public final String TAG = "ADManage";
    private int screenWidth;

    private AdsBanner admobBanner = new AdsBanner();
    private AdsInterstitial admobInterstitial = new AdsInterstitial();
    private AdsRewarded admobRewarded = new AdsRewarded();
    //-----------类型常量-------------
    private static String BANNER_TYPE = "0";
    private static String INTERSTITIAL_TYPE = "1";
    private static String NATIVE_TYPE = "2";
    private static String SPLASH_TYPE = "5";
    private static String REWARDED_TYPE = "8";
    //----------------------
    private static boolean isVideoRewarded = false;
    private static boolean isVideoClose = false;

    public static AdManage getInstance() {
        if (null == mInstace) {
            mInstace = new AdManage();
        }
        return mInstace;
    }

    public void init(Context context, int wid) {
        this.mainActive = context;
        this.screenWidth = wid;

        //初始化广告 SDK.
        // Make sure to set the mediation provider value to "max" to ensure proper functionality
        AppLovinSdk.getInstance( context ).setMediationProvider( "max" );
        AppLovinSdk.initializeSdk( context, new AppLovinSdk.SdkInitializationListener() {
            @Override
            public void onSdkInitialized(final AppLovinSdkConfiguration configuration)
            {
                // AppLovin SDK is initialized, start loading ads
                Log.d(AdManage.getInstance().TAG, "onInitializationComplete: ");
                FAEvent("Mobi_10001"); //广告初始化事件

            }
        } );

        //亲子同乐计划
      
//        RequestConfiguration requestConfiguration = MobileAds.getRequestConfiguration()
//                .toBuilder()
//                .setMaxAdContentRating(MAX_AD_CONTENT_RATING_G)
//                .setTagForChildDirectedTreatment(TAG_FOR_CHILD_DIRECTED_TREATMENT_TRUE)
//                .build();
//        MobileAds.setRequestConfiguration(requestConfiguration);


        admobBanner.init(this.mainActive,this.screenWidth);
        admobInterstitial.init(this.mainActive);
        admobRewarded.init(this.mainActive);

        loadBannerAd();
        loadInterstitalAd();
        initVideoAd();

        //开启广告测试界面
        //AppLovinSdk.getInstance( this.mainActive ).showMediationDebugger();

        //this.GetGAID(this.mainActive);
    }

    public String getUnitID(String type){
        if(type.equals(BANNER_TYPE)){
            return AD_BANNER_UNIT_ID;
        }else if(type.equals(REWARDED_TYPE)){
            return AD_VIDEO_ID;
        }else if(type.equals(INTERSTITIAL_TYPE)){
            return AD_UNIT_ID;
        }else{
            return "";
        }
    }

    public void GetGAID(Context context)
    {
        String GAID="";
        Context mActivity = context;
        new Thread(new Runnable() {
            public void run() {
                try {
                    AdvertisingIdClient.Info adInfo = AdvertisingIdClient
                            .getAdvertisingIdInfo(mActivity);
                    String advertisingId = adInfo.getId();
                    Log.d(AdManage.getInstance().TAG, "advertisingId: "+advertisingId);
                    // Log.i("ABC", "advertisingId" + advertisingId);
                    // Log.i("ABC", "optOutEnabled" + optOutEnabled);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    //---------旧版本失败打点------------
    public static void failFAEvent(int errorCode,String type){
        String eventName = type;
        if(errorCode == 3){
            eventName = eventName +"_NoFill";
        }else{
            eventName = eventName +"_CallFailed";
        }
        FireBaseAnalyticsManager.getInstance().FAEvent(eventName);
        Log.d(AdManage.getInstance().TAG, "errcode = "+errorCode);
        Log.d(AdManage.getInstance().TAG, "eventName = "+eventName);
    }
//    //--------------------
    //--------------新版本失败打点-----------
    public static void FAEventFail(String eventId,String unitId,String adType,String errorCode,String errorMessage){
        String[] key = {"unit_id","ad_type","error_code","error_msg"};
        String[] value = {unitId,adType,errorCode,errorMessage};
        FireBaseAnalyticsManager.getInstance().FAEventWithParFAEventam(eventId,key,value);
        Log.d(AdManage.getInstance().TAG, "eventID : "+eventId+"call Fail");
    }
    //------------------
    //---旧版本打点---------
    public static void successFAEvent(String type){
        String eventName = type;
        eventName = type+"_Success";
        FireBaseAnalyticsManager.getInstance().FAEvent(eventName);
        Log.d(AdManage.getInstance().TAG, "eventName = "+eventName);
    }
    //----------新版本打点------------------
    public static void FAEventSuccess(String eventID,String unitId,String adType){
        String[] key = {"unit_id","ad_type"};
        String[] value = {unitId,adType};
//        AdManage.getInstance().FAEventWithParam(eventID,key,value);
        FireBaseAnalyticsManager.getInstance().FAEventWithParFAEventam(eventID,key,value);
        Log.d(AdManage.getInstance().TAG, "eventID : "+eventID+"call success "+unitId);
    }
    //---------------------------

    public void FAEvent(String eventName){
        FireBaseAnalyticsManager.getInstance().FAEvent(eventName);
    }

    public void FAEventWithParam(String eventName , String[] key , String[] value){
        FireBaseAnalyticsManager.getInstance().FAEventWithParFAEventam(eventName,key,value);
    }

    /*
   加载google banner广告
 */
    public void loadBannerAd() {
        admobBanner.loadBannerAd();
    }

    /*
       显示google banner广告
     */
    public static void showBannerAd(String pos){
        AdManage.getInstance().admobBanner.showBannerAd(pos);
    }

    /*
   隐藏google banner广告
    */
    public static void hideBannerAd(){
        AdManage.getInstance().admobBanner.hideBannerAd();
    }

    public static void loadInterstitalAd(){
        AdManage.getInstance().admobInterstitial.loadInterstitalAd();
    }

    public static void showInterstitialAd() {
        AdManage.getInstance().admobInterstitial.showInterstitialAd();
    }

    public static void initVideoAd(){
        AdManage.getInstance().admobRewarded.initVideoAd();
    }

    //展示广告
    public static void showRewardVideoAd(){
        AdManage.getInstance().admobRewarded.showRewardVideoAd();
    }



    //用于cocos监听视频广告播放完成
    public static boolean videoRewardedListener(){
        return AdManage.getInstance().isVideoRewarded;
    }

    //用于cocos监听视频广告播放关闭
    public static boolean videoCloseListener(){
        return AdManage.getInstance().isVideoClose;
    }


    public boolean networkConnect() {
        return true;
    }

}
AppActivity
package org.cocos2dx.javascript;

import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;

import android.app.Service;
import android.os.Bundle;

import android.content.Intent;
import android.content.res.Configuration;
import android.os.Vibrator;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;

public class AppActivity extends Cocos2dxActivity {

    private static AppActivity app = null;
    private int screenWidth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Workaround in
        // https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508
        if (!isTaskRoot()) {
            // Android launched another instance of the root activity into an existing task
            // so just quietly finish and go away, dropping the user back into the activity
            // at the top of the stack (ie: the last state of this task)
            // Don't need to finish it again since it's finished in super.onCreate .
            return;
        }
        // DO OTHER INITIALIZATION BELOW
        SDKWrapper.getInstance().init(this);

        //屏幕常亮
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);


        //管理初始化
        initManager();
    }
    public void initManager(){
        app = this;
        //初始化firebase
        FireBaseAnalyticsManager.getInstance().init(this);
        //初始化app跳转
        JumpToApp.getInstance().init(this);
        getSize();
        //初始化广告管理
        AdManage.getInstance().init(this,this.screenWidth);
    }

    public void getSize() {
        // Step 2 - Determine the screen width (less decorations) to use for the ad width.
        Display display = getWindowManager().getDefaultDisplay();
        DisplayMetrics outMetrics = new DisplayMetrics();
        display.getMetrics(outMetrics);

        int widthPixels = outMetrics.widthPixels;
        int heightPixels = outMetrics.heightPixels;
        float density = outMetrics.density;

        int adWidth = (int) (widthPixels / density)/2;

        this.screenWidth = widthPixels;

        Log.d(AdManage.getInstance().TAG, "widthPixels: "+widthPixels);
        Log.d(AdManage.getInstance().TAG, "heightPixels: "+heightPixels);
        Log.d(AdManage.getInstance().TAG, "density: "+density);
        Log.d(AdManage.getInstance().TAG, "adWidth: "+adWidth);

    }

    //跳谷歌商城下的游戏页面=============================
//    public static void getAppByGooglePlay(String appPkg){
//        JumpToApp.getInstance().getAppByGooglePlay(appPkg);
//    }

    public  static  void vibrate(int time){
       // Log.d("vibrate", "shakeeeee: ");
        Vibrator vib=(Vibrator)app.getSystemService(Service.VIBRATOR_SERVICE);
        vib.vibrate(time);
    }

    @Override
    public Cocos2dxGLSurfaceView onCreateView() {
        Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
        // TestCpp should create stencil buffer
        glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
        SDKWrapper.getInstance().setGLSurfaceView(glSurfaceView, this);

        return glSurfaceView;
    }

    @Override
    protected void onResume() {
        super.onResume();
        SDKWrapper.getInstance().onResume();

    }

    @Override
    protected void onPause() {
        super.onPause();
        SDKWrapper.getInstance().onPause();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        // Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508
        if (!isTaskRoot()) {
            return;
        }

        SDKWrapper.getInstance().onDestroy();

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        SDKWrapper.getInstance().onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        SDKWrapper.getInstance().onNewIntent(intent);
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        SDKWrapper.getInstance().onRestart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        SDKWrapper.getInstance().onStop();
    }

    @Override
    public void onBackPressed() {
        SDKWrapper.getInstance().onBackPressed();
        super.onBackPressed();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        SDKWrapper.getInstance().onConfigurationChanged(newConfig);
        super.onConfigurationChanged(newConfig);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        SDKWrapper.getInstance().onRestoreInstanceState(savedInstanceState);
        super.onRestoreInstanceState(savedInstanceState);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        SDKWrapper.getInstance().onSaveInstanceState(outState);
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onStart() {
        SDKWrapper.getInstance().onStart();
        super.onStart();
    }
}
JumpToApp.java
package org.cocos2dx.javascript;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.text.TextUtils;

import java.util.ArrayList;
import java.util.List;

//从商城获取app,或者打开本地
public class JumpToApp {
    private static JumpToApp mInstace = null;
    //得到版本号
    public static String versionName;

    private Context mainActive = null;
    public static JumpToApp getInstance() {
        if (null == mInstace) {
            mInstace = new JumpToApp();
        }
        return mInstace;
    }

    public void init(Context context){
        mainActive = context;
    }
    //跳谷歌商城下的游戏页面=============================
    public static void getAppByGooglePlay(String appPkg){
        mInstace.appUpdate(JumpToApp.getInstance().mainActive,appPkg,"com.android.vending");
    }
    /**
     * 判断应用市场是否存在的方法
     * @param context
     * @param packageName
     * 主流应用商店对应的包名
     *  com.android.vending    -----Google Play
     *  com.tencent.android.qqdownloader    -----应用宝
     *  com.qihoo.appstore    -----360手机助手
     *  com.baidu.appsearch    -----百度手机助
     *  com.xiaomi.market    -----小米应用商店
     *  com.wandoujia.phoenix2    -----豌豆荚
     *  com.huawei.appmarket    -----华为应用市场
     *  com.taobao.appcenter    -----淘宝手机助手
     *  com.hiapk.marketpho    -----安卓市场
     *  cn.goapk.market        -----安智市场
     * @return
     */
    public static boolean isAvilible(Context context, String packageName){
        // 获取packagemanager
        final PackageManager packageManager = context.getPackageManager();
        // 获取所有已安装程序的包信息
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
        // 用于存储所有已安装程序的包名
        List<String> pName = new ArrayList<String>();
        // 从pinfo中将包名字取出
        if (pinfo != null){
            for (int i = 0; i < pinfo.size(); i++){
                String pf = pinfo.get(i).packageName;
                pName.add(pf);
            }
        }
        // 判断pName中是否有目标程序的包名,有true,没有false
        return pName.contains(packageName);

    }

    //得到版本号
    public static void getVersionName(Context context){
        PackageManager manager = context.getPackageManager();
        try{
            PackageInfo info = manager.getPackageInfo(context.getPackageName(),0);
            versionName = info.versionName;
        }catch (PackageManager.NameNotFoundException e){
            e.printStackTrace();
        }
    }

    private void appUpdate(Context context,String appPkg, String marketPkg){
        //判断应用市场是否有包名
        if(isAvilible(context,appPkg)){
            Intent intent = context.getPackageManager().getLaunchIntentForPackage(appPkg);
            context.startActivity(intent);
        }else if(isAvilible(context,marketPkg)){
            launchAppDetail(context,appPkg,marketPkg);
        }else { //没有,用浏览器打开地址进行下载
            //安装市场应用,那么根据后台返回的地址,用浏览器打开地址进行下载
            //Uri uri = Uri.parse(url);
            //Intent intent =new Intent(Intent.ACTION_VIEW, uri);
            //startActivity(intent);
        }
        //Toast.makeText(this,"立即更新",Toast.LENGTH_LONG).show();
    }

    /**
     * 启动到应用商店app详情界面
     * @param mContext
     * @param appPkg 目标App的包名
     * @param marketPkg 应用商店包名 ,如果为""则由系统弹出应用商店列表供用户选择,否则调转到目标市场的应用详情界面
     */
    //跳转更新
    public static void launchAppDetail(Context mContext, String appPkg, String marketPkg){
        try{
            if (TextUtils.isEmpty(appPkg)){
                return;
            }
            Uri uri = Uri.parse("market://details?id=" + appPkg);
            Intent intent =new Intent(Intent.ACTION_VIEW, uri);
            if (!TextUtils.isEmpty(marketPkg)){
                intent.setPackage(marketPkg);
            }
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
FireBaseAnalyticsManager.java(打点统计)
package org.cocos2dx.javascript;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;

import com.google.firebase.analytics.FirebaseAnalytics;


public class FireBaseAnalyticsManager {
    private static FireBaseAnalyticsManager mInstace = null;
    private FirebaseAnalytics mFirebaseAnalytics;
    private Context mainActive = null;
    private static final String Tag = "firebase";
    //private Map<String, Integer> eventCount =null;
    private static long beginTime ;
    private static long endTime ;

    public static FireBaseAnalyticsManager getInstance() {
        if (null == mInstace) {
            mInstace = new FireBaseAnalyticsManager();
        }
        return mInstace;
    }

    public void init(Context context){
        this.mainActive = context;
        mFirebaseAnalytics = FirebaseAnalytics.getInstance(context);
    }

    public static void FAEvent(String eventName){
        Log.d(Tag, "FAEvent"+eventName);
        Bundle params = new Bundle();
       // params.putString("value","nul");
        FireBaseAnalyticsManager.getInstance().mFirebaseAnalytics.logEvent(eventName, params);
    }

    public static void FAEventWithParFAEventam(String eventName , String[] key , String[] value){
        Log.d(Tag, "FAEventWithParFAEventam = "+eventName);
        int paramLength = key.length;
        Log.d(Tag, "paramLength"+paramLength);
        Bundle params = new Bundle();
        for(int i = 0;i<paramLength;i++){
            params.putString(key[i],value[i]);
        }
        FireBaseAnalyticsManager.getInstance().mFirebaseAnalytics.logEvent(eventName, params);
    }

    public static void FAEventWithParFAEventam(String eventName , String key , String value){
        Log.d(Tag, "FAEventWithParFAEventam = "+eventName);
        Bundle params = new Bundle();
        params.putString(key,value);
        FireBaseAnalyticsManager.getInstance().mFirebaseAnalytics.logEvent(eventName, params);
    }

    public static void FAEventBegin(String eventName){
        Log.d(Tag, "FAEventBegin = "+eventName);
        beginTime = System.currentTimeMillis();
        Bundle params = new Bundle();
        // params.putString("value","nul");
        FireBaseAnalyticsManager.getInstance().mFirebaseAnalytics.logEvent(eventName, params);
    }

    public static void FAEventEnd(String eventName){
        Log.d(Tag, "FAEventEnd = "+eventName);
        endTime = System.currentTimeMillis();
        double betweenTime = (endTime - beginTime)/1000.0;
        Bundle params = new Bundle();
        String.valueOf(betweenTime);
         params.putString("time", String.valueOf(betweenTime));
        FireBaseAnalyticsManager.getInstance().mFirebaseAnalytics.logEvent(eventName, params);
        Log.d(Tag, "eventTime = "+betweenTime);
    }
}

cocos Android 互相调用

import GameManager from "./GameManager";

const { ccclass, property } = cc._decorator;

@ccclass
export default class PlatformApi {

    private static _instance: PlatformApi | null = null;

    public static get Instance() {

        if (!PlatformApi._instance) {
            window["PlatformApi"] = new PlatformApi();
            PlatformApi._instance = new PlatformApi()
        }
        // return PlatformApi._instance || (PlatformApi._instance = new PlatformApi());
        return PlatformApi._instance;
    }

    // 是否预加载激励广告
    public isLoadRewardAd: boolean = false;

    // 申请激励广告时间
    public showRewardVideoADTime: number = 0;

    public vibrateNum: number = 0;

    // 震动时间
    public VibrateTime: number = 0;

    // 是否ios平台
    public isPlatformIos() {
        let bIos = false;
        if (cc.sys.os == cc.sys.OS_IOS) {
            bIos = true;
        }
        return bIos;
    }

    /**
     * 
     * @param dir bottom-lefte 左下 top 顶部居中 bottom 底部居中 top-lefte
     */
    public showBanner(dir: string) {
        cc.log("广告 showBanner");
        //eg
        //jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AdManage", "showBannerAd", "(Ljava/lang/String;)V", "bottom-left");
        jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AdManage", "showBannerAd", "(Ljava/lang/String;)V", dir);

    }
    /**隐藏banner */
    public hideBanner() {
        cc.log("广告 hideBanner");
        jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AdManage", "hideBannerAd", "()V");
    }

    timeCount=120;
    //这个计时得在其他常驻节点上调用
    public UpdateInterstitialAd()
    {
        PlatformApi.Instance.timeCount++;
        //cc.log("timeCount "+PlatformApi.Instance.timeCount);

    }

    //展示插屏广告
    public showInterstitialAd(time=35) {
        cc.log("广告 插屏广告");
        //35秒内触发一次,不需要的话可以注释掉
        if (this.timeCount<time) {
            cc.log("广告 "+this.timeCount+" 短时间内重复触发");
            return;
        }      

        jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AdManage", "showInterstitialAd", "()V");
    }

    //展示激励广告
    public showRewardVideoAD() {
        // =================================
        let newTime = new Date().getTime();
        if ((newTime - PlatformApi.Instance.showRewardVideoADTime) < 5000) {
            cc.game.emit("_no_5_seconds_");
            // console.log("5秒内不能重复请求");
            return;
        }
        PlatformApi.Instance.showRewardVideoADTime = newTime;
        //  =================================
        console.log("广告 激励广告");
        jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AdManage", "showRewardVideoAd", "()V");
    }

    // 
    public jumpToApp(appPkg: string) {
        if (cc.sys.os == cc.sys.OS_ANDROID) {
            jsb.reflection.callStaticMethod("org/cocos2dx/javascript/JumpToApp", "getAppByGooglePlay", "(Ljava/lang/String;)V", appPkg);
        } else if (cc.sys.os == cc.sys.OS_IOS) {
            jsb.reflection.callStaticMethod("CommonManager", "jumpToApp:", appPkg);
        }
    }

    // 打点
    public FAEvent(eventName: string) {
        cc.log("FAEvent 打点 = " + eventName);
        jsb.reflection.callStaticMethod("org/cocos2dx/javascript/FireBaseAnalyticsManager", "FAEvent", "(Ljava/lang/String;)V", eventName);
    }
    public FAEventWithStringParam(eventName: string, key: string, value: string) {
        jsb.reflection.callStaticMethod("org/cocos2dx/javascript/FireBaseAnalyticsManager", "FAEventWithParFAEventam", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", eventName, key, value);
    }

    public FAEventBegin(eventName: string) {
        cc.log("FAEventBegin 打点 = " + eventName);
        jsb.reflection.callStaticMethod("org/cocos2dx/javascript/FireBaseAnalyticsManager", "FAEventBegin", "(Ljava/lang/String;)V", eventName);
    }

    public FAEventEnd(eventName: string) {
        cc.log("FAEventEnd 打点 = " + eventName);
        jsb.reflection.callStaticMethod("org/cocos2dx/javascript/FireBaseAnalyticsManager", "FAEventEnd", "(Ljava/lang/String;)V", eventName);
    }


    // 回调=================================================================================
    // 安卓广告播放成功回调
    // 安卓广告播放成功回调
    public getVideoReward() {
        console.log("ADManage getVideoReward");
        cc.game.emit("_get_video_reward_");
    }
    // 广告回调失败是因为缺少库存,显示本地广告
    public showRewardVideoADFailByAndroid() {
        console.log("ADManage showRewardVideoADFailByAndroid");
        cc.game.emit("_show_reward_video_AD_fail_");
    }

    // 插屏广告关闭
    public getInterstitalHidden() {
        console.log("ADManage getInterstitalHidden");
        PlatformApi.Instance.timeCount=0;
    }

    //视频广告关闭
    public getVideoHidden() {
        console.log("ADManage getVideoHidden");
        PlatformApi.Instance.timeCount=0;
    }
}

MAX  Mediation Debugger 使用说明(中介广告测试)

MAX Mediation Documentationhttps://dash.applovin.com/documentation/mediation/android/testing-networks/mediation-debugger AppLovinSdk.getInstance( this ).showMediationDebugger();

 

 

 

补充: 

升级cocos creator 为3.4.2 版本后发现AS目录结构不同了,在Project 模式下很多东西看不到了,所以选择Android模式更清晰点,

 

 升级gradle版本不在需要了。

安卓回掉cocos需要改成这样:

CocosHelper.runOnGameThread(new Runnable() {
    @Override
    public void run() {
        CocosJavascriptJavaBridge.evalString("window.PlatformApi.getVideoReward()");
        Log.d(AdManage.getInstance().TAG, "call Rewarded");
    }
});

 其他设置基本不变,根据提示修改就行

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CososCreator (Android)-AppLovin MAX 广告聚合平台接入+Firebase统计 的相关文章

  • 这个方法比 Math.random() 更快吗?

    我是一名初学者 目前已经开始开发一款使用粒子群优化算法的 Android 游戏 我现在正在尝试稍微优化我的代码 并且 for 循环中有相当多的 Math random 几乎一直在运行 所以我正在考虑一种方法来绕过并跳过所有 Math ran
  • Android上如何模拟后台Activity因内存不足而被系统杀死的过程?

    我正在处理 内存不足 不再有后台进程 问题 当这种情况发生时 我的活动处于后台并被杀死 我正在尝试保存并加载实例状态来解决它 但因为它并不是每次都会发生 在这种情况下我应该如何测试我的活动 Thanks 您可以通过 adb 强制进程终止 g
  • 需要使用手机后退按钮返回 Web 视图的帮助

    这是我的代码 package com testappmobile import android app Activity import android os Bundle import android view KeyEvent impor
  • 如何在 android 中启动“添加联系人”活动

    您能告诉我如何在 Android 中启动 添加联系人 活动吗 谢谢 API 级别 5 及以上解决方案 Add listener so your activity gets called back upon completion of act
  • API29 上不推荐使用 setColorFilter

    我使用以下行来更改 VectorDrawable 的颜色 mydrawable getBackground setColorFilter color PorterDuff Mode SRC ATOP 这很好用 尽管它现在已被弃用 文档建议我
  • 如何在 Android TextView 中使用土耳其语字符,如“ş ç ı ö”?

    我想在 android TextView 中写入 ile 但它没有正确绘制 怎样才能使用这样的字符呢 例如 我将文本视图设置为 ile 它显示为 ile 我怎样才能解决这个问题 尝试以下方法 看看是否有帮助 source http grou
  • 不变违规:requireNativeComponent:在 UIManager 中找不到“RNSVGSvgViewAndroid”

    我对标题中提到的错误感到头疼 我正在使用react native gifted charts https www npmjs com package react native gifted charts v 1 0 3 https www
  • 位图内存不足错误

    我对这个错误有疑问 我从 URL 制作网站图标解析器 我这样做是这样的 public class GrabIconsFromWebPage public static String replaceUrl String url StringB
  • 我想从 android 中服务器的视频 url 创建缩略图

    My code public static Bitmap retriveVideoFrameFromVideo String videoPath throws Throwable Bitmap bitmap null MediaMetada
  • 在选项卡上保存数据

    我有 3 个选项卡 每个选项卡都有一个单独的活动 我想在用户单击任一选项卡上的 保存 时保存数据 有几个选项可供选择 共享首选项 全局变量或将对象保存在上下文中 编辑 我必须保存图像和文本字段 Android 共享首选项 https sta
  • 像 WhatsApp 一样发送图片

    我做了一个聊天应用程序 我想添加照片 文件共享我的应用程序中的概念与 WhatsApp 相同 我已经使用该应用程序制作了Xmpp Openfire目前我正在使用此功能进行照片共享 但它并不完全可靠 public void sendFile
  • 具有代理设置的 Android 模拟器 - 致命错误:.//android/base/sockets/ 检查失败:isValidFd(fd)。 FD 1404 最大1024

    需要使用代理设置运行模拟器 我在命令提示符中使用以下命令来启动模拟器 emulator avd AVD for 3 7 WVGA Nexus One http proxy http username password IP Port 如果没
  • 适用于 Android 的 Google 云端硬盘\文档 API

    我在几个小时内将 Dropbox 与我的应用程序集成 因为 SDK 描述清晰并且有很好的使用示例 Google Drive 似乎只有一个 一刀切 的 Gdata SDK 它非常重 有很多依赖项 它使我的应用程序的大小增加了三倍 而且不是很直
  • Android 纹理仅显示纯色

    我正在尝试在四边形上显示单个纹理 我有一个可用的 VertexObject 它可以很好地绘制一个正方形 或任何几何对象 现在我尝试扩展它来处理纹理 但纹理不起作用 我只看到一种纯色的四边形 坐标数据位于 arrayList 中 the ve
  • 有多少种方法可以将位图转换为字符串,反之亦然?

    在我的应用程序中 我想以字符串的形式将位图图像发送到服务器 我想知道有多少种方法可以将位图转换为字符串 现在我使用 Base64 格式进行编码和解码 它需要更多的内存 是否有其他可能性以不同的方式做同样的事情 从而消耗更少的内存 现在我正在
  • Android 时钟滴答数 [赫兹]

    关于 proc pid stat 中应用程序的总 CPU 使用率 https stackoverflow com questions 16726779 total cpu usage of an application from proc
  • Android 中的列表视图分页

    我有一个列表视图 其中显示了 50 个元素 我决定对视图进行分页 以便视图的每个部分都有 10 个元素 然后单击 下一个 按钮以获取下一个 10 个元素 如何设置10个数据 我关注这篇文章http rakhi577 wordpress co
  • 屏幕开/关检测

    在这里 我试图确定屏幕是否打开 但按下电源锁定 解锁按钮时它似乎不起作用 应用程序运行没有错误 但 if else 中的代码似乎没有效果 Edited现在代码可以工作了 谢谢Olgun 但媒体播放器播放不会停止 并且每次在屏幕上 离屏时都会
  • 使用 DataBindingComponent 的 Inflate 方法

    当 Glide 成功渲染图像后 我在更新文本视图时看到此错误 致命异常 java lang IllegalStateException 必需 CustomBinding 类中的 DataBindingComponent 为 null 绑定适
  • 将焦距(以毫米为单位)转换为像素 - Android

    在 Android 中 我当前正在访问camera s焦距通过使用getFocalLength in Camera1 Camera2不是一个选择 我正在尝试完全填充当前的计算 focal length pix focal length m

随机推荐

  • 虚拟IP原理

    高可用性HA High Availability 指的是通过尽量缩短因日常维护操作 计划 和突发的系统崩溃 非计划 所导致的停机时间 以提高系统和应用的可用性 HA系统是目前企业防止核心计算机系统因故障停机的最有效手段 实现HA的方式 一般
  • java x86 x64_jdk x86与jdk x64 有什么区别

    展开全部 1 jdk x86与jdk x64版本不同 jdk x86 32位版e68a843231313335323631343130323136353331333431366239 jdk x64 64位版 2 jdk x86与jdk x
  • c++ enable_shared_from_this

    std enable shared from this 是一个类模板 那它是用来干嘛的呢 光看它的名字可能可以猜出它是 返回指向当前对象的shared ptr智能指针 在说明它的作用前我们可以看一下如下代码 include
  • ceph分布式文件存储性能调优

    ceph分布式文件存储性能调优 一 硬件调优 二 BIOS配置 三 网络配置 四 OS配置 五 硬盘调度算法 六 软件层面 七 ceph参数调优 一 硬件调优 1 NVMe SSD 调优 目的 为减少数据跨片开销 方法 将NVMe SSD与
  • 彩笔的第一个模型:DOTA数据集YOLOv5目标检测

    目录 前言 一 下载数据集DOTA和源码 下载YOLOv5模型 切割图片并转化label为YOLO格式 2 DOTA数据集的label格式不能在YOLO模型 里直接使用 需要转化 3 需要做成coco数据集的文件结构 包括文件夹名称 二 修
  • 技术科普丨信噪比

    概念简介 信噪比 英文名称叫做SNR或S N SIGNAL NOISE RATIO 又称为讯噪比 是指一个电子设备或者电子系统中信号与噪声的比例 信噪比的计量单位是dB 对于一张图像来说 计算信噪比可以按照 20lg 信号 噪声 这个公式来
  • Andriod getContext和getActivity

    原创文章 如有转载 请注明出处 http blog csdn net myth13141314 article details 62045162 MainActivity this 表示MainActivity对象 一般用在内部类中指示外面
  • STM32+FATFS文件系统连续在同一个txt文件里写入内容

    移植好fatfs文件系统之后 我们经常要在一个txt文件下写入数据 但是这些数据可能需要多次写入 那怎么办呢 通过这几天的学习 有以下函数可以帮助我们进行多次写入数据 1 打开文件 f open filescr2 0 201711022 t
  • CAN资料整理(三):CAN的位时间、同步、位定时

    目录 一 位时间 二 同步 1 硬同步 2 重新同步 三 位定时 1 传播段延迟时间的确定 2 位定时参数确定 由于CAN属于异步通讯 没有时钟信号线 连接在同一个总线网络中的各个节点会像串口异步通讯那样 节点间会使用约定好的波特率进行通讯
  • ROS+UR机械臂系列-1- 虚拟机及ROS安装

    ROS UR机械臂系列 1 虚拟机及ROS安装 小白 刚开始使用ROS系统 希望可以成一个系列 方便大家参考 避过大坑 最开始使用的是Ubuntu20 04 ROS noetic 遇到问题时 发现很多都在用Ubuntu18 04 ROS m
  • 解决pip安装包时出现 WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))

    错误描述 anaconda使用pip安装包时会出现无法下载的问题 或者pip直接无反应 可能会出现如下错误提示 WARNING Retrying Retry total 4 connect None read None redirect N
  • 微服务内部服务调用@Inner

    1 外部从Gateway访问 需要鉴权 eg CURD操作 这种是最常使 的 户登录后正常访问接 不需要我们做什么处理 可能有的接 需要加权限字段 2 外部从Gateway访问 不需要鉴权 eg 短信验证码 需要我们将uri加 到secur
  • SLF4J分析

    slf4j Simple Logging Facade for Java 为java提供的简单日志Facade Facade 门面 更底层一点说就是接口 他允许用户以自己的喜好 在工程中通过slf4j接入不同的日志系统 更直观一点 slf4
  • 基于matlab实现平均移动法

    平均移动法 基于matlab实现 代码如下 示例 clc clear load xy mat x y m length y n 4 5 6 7 10 20 n 为移动平均的项数 l length n for i 1 length n 由于
  • 阿里云服务器更换操作系统流程(新版教程)

    阿里云服务器操作系统选择后还可以更改吗 可以的 重装操作系统是免费的 但是需要注意中国大陆地域可以随意更换 中国香港 新加坡等非中国大陆地域的云服务器不支持Windows和Linux操作系统之间变换 阿里云百科来详细说下阿里云服务器重装操作
  • CentOS8、Ubuntu安装mysql5.7,修改密码、配置远程访问、开机自启、创建开发者账户(超级详细)

    下载MYSQL wget http dev mysql com get mysql80 community release el7 3 noarch rpm 安装MYSQL RPM 模块 rpm ivh mysql80 community
  • m3u8文件

    EXTM3U m3u文件头 必须放在第一行 起标示作用 EXT X VERSION 播放列表文件的兼容版本 若不存在此标记 则默认为协议的第一个版本 EXT X MEDIA SEQUENCE 播放列表中的每个媒体 URI 都有一个唯一的整数
  • docker容器内修改配置文件

    一 vim修改 1 进入容器内部 docker exec it id bin bash 2 安装vim 输入命令 apt get update apt get install vim 二 替换配置文件 1 替换配置文件 docker cp
  • 最火前端Web组态软件(可视化)

    前言 随着物联网 大数据等技术高速发展 我们逐步向数字化 可视化的人工智能 AI 时代的方向不断迈进 智能时代是工业 4 0 时代 我国工业领域正努力从 制造 迈向 智造 的新跨越 正文 1 mxgraph 介绍 开源免费 但是需要解决的问
  • CososCreator (Android)-AppLovin MAX 广告聚合平台接入+Firebase统计

    CososCreator 2 4 4 Android Studio 4 2 1 接入SDK有 接max聚合及中介平台 Admob FB applovin pangle mintegral vungle unity 和Firebase 统计