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.
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 密钥:
添加到应用程序级 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
gradle.properties中加入:
android.useAndroidX=trueandroid.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
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.Osapply 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); } 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) { } @Override public void onAdHidden(final MaxAd maxAd) { } }); } 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); } }); } 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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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); } public void loadBannerAd() { admobBanner.loadBannerAd(); } public static void showBannerAd(String pos){ AdManage.getInstance().admobBanner.showBannerAd(pos); } 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"); } public static boolean isAvilible(Context context, String packageName){ // 获取packagemanager final PackageManager packageManager = context.getPackageManager(); // 获取所有已安装程序的包信息 List pinfo = packageManager.getInstalledPackages(0); // 用于存储所有已安装程序的包名 List pName = new ArrayList(); // 从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(); } //跳转更新 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 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
cocos Android 互相调用
import GameManager from "./GameManager";const { ccclass, property } = cc._decorator;@ccclassexport 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; } 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); } 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
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"); }});
其他设置基本不变,根据提示修改就行
来源地址:https://blog.csdn.net/weixin_41843959/article/details/128241823