当前位置: 首页 > news >正文

unity sdk -AppLovin MAX 广告聚合平台接入+Firebase统计

unity版本:2019.4.40f1

Android Studio :4.2.1

sdk版本:5.4.6

max对应unity的官方文档:

MAX Mediation Documentationhttps://dash.applovin.com/documentation/mediation/unity/getting-started/integration

1、阅读官方文档 下载sdk 全部导入

 2、集成器设置

 a、集成max SDK 的更新 

b、其他中介平台组加入(我这边加入了 google admob 和Mintegral和Pangle 三个中介平台)

 c、Applovin  key 添加,其他部分根据需求一般保持不变

 d、Android 配置设置

 3、Firebase接入

Firebase接入文档https://mp.csdn.net/mp_blog/creation/editor/126500929

按以上文档接入,需要注意 以上已经接入了google admob的sdk,所以Firebase sdk里面的google部分会冲突,所以冲突部分不需要导入

设置完所有平台和其他插件后Force Resolve 下,就会下载所需的.arr文件

例如: 

 

4、代码初始化调用

using System.Collections;
using UnityEngine;
using System.Collections.Generic;
using System;

public class ServicesManager_MAX : MonoBehaviour
{
    public static ServicesManager_MAX instance { get; set; }

    public bool openShowOpenAD = true;
    public bool openShowBanner = false;

    public string appIDAndroid;
    public string appOpenIDAndroid;
    public string bannerIDAndroid;
    public string interstitialID;
    public string rewardedVideoAdsID;

    bool isRewardAdded;

    [Header("IOS")]
    public string appIDIos;
    public string appOpenIDIos;
    public string bannerIDIos;
    public string interstitialIDIos;
    public string rewardedVideoAdsIDIos;

    private string sdkKey;
    private string appOpenID;
    private string bannerID;
    private string InterstitialsID;
    private string VideoID;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(this.gameObject);
        }
        else
        {
            GameObject.Destroy(this.gameObject);
        }
    }

#if ADS_MAX
    void Start()
    {
        Application.targetFrameRate = 60;

        if (Application.platform == RuntimePlatform.IPhonePlayer)
        {
            sdkKey = appIDIos;
            bannerID = bannerIDIos;
            InterstitialsID = interstitialIDIos;
            VideoID = rewardedVideoAdsIDIos;
        }
        else
        {
            sdkKey = appIDAndroid;
            bannerID = bannerIDAndroid;
            InterstitialsID = interstitialID;
            VideoID = rewardedVideoAdsID;
        }

        //---test--start--测试id
//        sdkKey = "ENTER_MAX_SDK_KEY_HERE";
//        bannerID = "ENTER_BANNER_AD_UNIT_ID_HERE";
// 
//         InterstitialsID = "ENTER_INTERSTITIAL_AD_UNIT_ID_HERE";
//         VideoID ="ca-app-pub-ENTER_REWARD_AD_UNIT_ID_HERE/5224354917";
// 
        //---test---end-

        InitMAX();
    }

    void InitMAX()
    {
        MaxSdkCallbacks.OnSdkInitializedEvent += (MaxSdkBase.SdkConfiguration sdkConfiguration) =>
        {
            if (sdkConfiguration.ConsentDialogState == MaxSdkBase.ConsentDialogState.Applies)
            {
                //MaxSdk.SetHasUserConsent(true);
                //MaxSdk.SetHasUserConsent(false);
                // Show user consent dialog
                //MaxSdk.UserService.ShowConsentDialog();
            }
            else if (sdkConfiguration.ConsentDialogState == MaxSdkBase.ConsentDialogState.DoesNotApply)
            {
                // No need to show consent dialog, proceed with initialization
            }
            else
            {
                // Consent dialog state is unknown. Proceed with initialization, but check if the consent
                // dialog should be shown on the next application initialization
            }

            // AppLovin SDK is initialized, start loading ads
            InitAD();
            CheckFirebase();
        };

        MaxSdk.SetSdkKey(sdkKey);
        //MaxSdk.SetUserId("USER_ID");
        MaxSdk.InitializeSdk();
        //MaxSdk.InitializeSdk(new[] { "YOUR_AD_UNIT_ID_1", "YOUR_AD_UNIT_ID_2" });

        //MaxSdk.SetVerboseLogging(true);
    }

    void InitAD()
    {
        if (openShowBanner)
        {
            InitializeBannerAds();
        }

        if (openShowOpenAD)
        {
            InitializeOpenAd();
        }
        //

        Invoke("InitializeInterstitialAds", 0.5f);
        Invoke("InitializeRewardedAds", 1f);
    }


    void CheckFirebase()
    {
        Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
        {
            var dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available)
            {
                // Create and hold a reference to your FirebaseApp,
                // where app is a Firebase.FirebaseApp property of your application class.
                //app = Firebase.FirebaseApp.DefaultInstance;

                // Set a flag here to indicate whether Firebase is ready to use by your app.
                Debug.Log("Create and hold a reference to your FirebaseApp");
            }
            else
            {
                UnityEngine.Debug.LogError(System.String.Format(
                  "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
                // Firebase Unity SDK is not safe to use here.
            }
        });
    }
#endif

        private void Update()
    {
        AdOpenTime += Time.deltaTime;
    }

    //-----------------------------------横幅---------------------------------------------
#if ADS_MAX
    public void InitializeBannerAds()
    {
        // Banners are automatically sized to 320×50 on phones and 728×90 on tablets
        // You may call the utility method MaxSdkUtils.isTablet() to help with view sizing adjustments
        MaxSdk.CreateBanner(bannerID, MaxSdkBase.BannerPosition.TopCenter);
        //MaxSdk.SetBannerExtraParameter(bannerAdUnitId, "adaptive_banner", "true")

        // Set background or background color for banners to be fully functional
        MaxSdk.SetBannerBackgroundColor(bannerID,new Color(1,1,1,0));

        MaxSdkCallbacks.Banner.OnAdLoadedEvent      += OnBannerAdLoadedEvent;
        MaxSdkCallbacks.Banner.OnAdLoadFailedEvent  += OnBannerAdLoadFailedEvent;
        MaxSdkCallbacks.Banner.OnAdClickedEvent     += OnBannerAdClickedEvent;
        MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent += OnBannerAdRevenuePaidEvent;
        MaxSdkCallbacks.Banner.OnAdExpandedEvent    += OnBannerAdExpandedEvent;
        MaxSdkCallbacks.Banner.OnAdCollapsedEvent   += OnBannerAdCollapsedEvent;
    }

    private void OnBannerAdLoadedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
    {
        //Invoke("ShowBannerAdmob", 1);
        ShowBannerAdmob("", "");
    }

    private void OnBannerAdLoadFailedEvent(string adUnitId, MaxSdkBase.ErrorInfo errorInfo) {}

    private void OnBannerAdClickedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo) {}

    private void OnBannerAdRevenuePaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo) {}

    private void OnBannerAdExpandedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)  {}

    private void OnBannerAdCollapsedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo) {}
#endif

    public void ShowBannerAdmob(string eventName, object data)
    {
        Debug.Log("ShowBannerAdmob loaded succesfully");
#if ADS_MAX
        MaxSdk.ShowBanner(bannerID);
#endif
    }

    public void HideBanner()
    {
#if ADS_MAX
        MaxSdk.HideBanner(bannerID);
#endif
    }

    //-----------------------------------自制开屏(用插屏当开屏)---------------------------------------------
#if ADS_MAX
    bool isOnceOpenAd = false;
    void InitializeOpenAd()
    {
        isOnceOpenAd = true;
    }

#endif

    //-----------------------------------插页---------------------------------------------
#if ADS_MAX
    int retryAttemptInterstitial;

    DateTime lastNow = DateTime.Now;
    public void InitializeInterstitialAds()
    {
        // Attach callback
        MaxSdkCallbacks.Interstitial.OnAdLoadedEvent += OnInterstitialLoadedEvent;
        MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent += OnInterstitialLoadFailedEvent;
        MaxSdkCallbacks.Interstitial.OnAdDisplayedEvent += OnInterstitialDisplayedEvent;
        MaxSdkCallbacks.Interstitial.OnAdClickedEvent += OnInterstitialClickedEvent;
        MaxSdkCallbacks.Interstitial.OnAdHiddenEvent += OnInterstitialHiddenEvent;
        MaxSdkCallbacks.Interstitial.OnAdDisplayFailedEvent += OnInterstitialAdFailedToDisplayEvent;

        // Load the first interstitial
        LoadInterstitial();
    }

    private void LoadInterstitial()
    {
        MaxSdk.LoadInterstitial(InterstitialsID);
    }

    private void OnInterstitialLoadedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
    {
        // Interstitial ad is ready for you to show. MaxSdk.IsInterstitialReady(adUnitId) now returns 'true'

        // Reset retry attempt
        retryAttemptInterstitial = 0;

        DateTime newTime = DateTime.Now;
        TimeSpan ts1 = new TimeSpan(lastNow.Ticks);
        TimeSpan ts2 = new TimeSpan(newTime.Ticks);
        TimeSpan tsSub = ts1.Subtract(ts2).Duration();
        if (tsSub.TotalSeconds < 5 && isOnceOpenAd)
        {
            Debug.Log("OpenAd loaded succesfully");
            isOnceOpenAd = false;
            ShowInterstitialAdmob("ShowInterstitialAdmob", "");
        }
    }

    private void OnInterstitialLoadFailedEvent(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
    {
        // Interstitial ad failed to load 
        // AppLovin recommends that you retry with exponentially higher delays, up to a maximum delay (in this case 64 seconds)
        print("OnInterstitialLoadFailedEvent Name: " + errorInfo.WaterfallInfo.Name + " and Test Name: " + errorInfo.WaterfallInfo.TestName);

        retryAttemptInterstitial++;
        double retryDelay = Math.Pow(2, Math.Min(6, retryAttemptInterstitial));

        Invoke("LoadInterstitial", (float)retryDelay);
    }

    private void OnInterstitialDisplayedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo) { }

    private void OnInterstitialAdFailedToDisplayEvent(string adUnitId, MaxSdkBase.ErrorInfo errorInfo, MaxSdkBase.AdInfo adInfo)
    {
        // Interstitial ad failed to display. AppLovin recommends that you load the next ad.
        LoadInterstitial();
    }

    private void OnInterstitialClickedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo) { }

    private void OnInterstitialHiddenEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
    {
        // Interstitial ad is hidden. Pre-load the next ad.
        LoadInterstitial();
    }
#endif

    //带回掉的展示插屏
    public void ShowInterstitialAdmob(string eventName, object data)
    {
#if ADS_MAX
        click = (System.Action)data;

        if (MaxSdk.IsInterstitialReady(InterstitialsID))
        {
            Debug.Log("Interstitial was loaded succesfully! interstialId=" + InterstitialsID[0]);
            MaxSdk.ShowInterstitial(InterstitialsID);
        }
        else
        {
            Debug.Log("Interstitial Loding " + InterstitialsID);
        }
#endif
    }

    //限制时间的回掉插屏
    float AdOpenTime = 120f;
    public void ShowInterstitialAdmobTime(string eventName, object data)
    {
        if (AdOpenTime < (int)data)
        {
            return;
        }

#if ADS_MAX
        click = null;
        if (MaxSdk.IsInterstitialReady(InterstitialsID))
        {
            AdOpenTime = 0;
            Debug.Log("Interstitial was loaded succesfully! interstialId=" + InterstitialsID[0]);
            MaxSdk.ShowInterstitial(InterstitialsID);
        }
        else
        {
            Debug.Log("Interstitial Loding " + InterstitialsID);
        }
#endif
    }


    //-----------------------------------激励视频---------------------------------------------
#if ADS_MAX
    System.Action click;

    int retryAttemptRewarded=0;

    public void InitializeRewardedAds()
    {
        // Attach callback
        MaxSdkCallbacks.Rewarded.OnAdLoadedEvent += OnRewardedAdLoadedEvent;
        MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent += OnRewardedAdLoadFailedEvent;
        MaxSdkCallbacks.Rewarded.OnAdDisplayedEvent += OnRewardedAdDisplayedEvent;
        MaxSdkCallbacks.Rewarded.OnAdClickedEvent += OnRewardedAdClickedEvent;
        MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent += OnRewardedAdRevenuePaidEvent;
        MaxSdkCallbacks.Rewarded.OnAdHiddenEvent += OnRewardedAdHiddenEvent;
        MaxSdkCallbacks.Rewarded.OnAdDisplayFailedEvent += OnRewardedAdFailedToDisplayEvent;
        MaxSdkCallbacks.Rewarded.OnAdReceivedRewardEvent += OnRewardedAdReceivedRewardEvent;

        // Load the first rewarded ad
        LoadRewardedAd();
    }

    private void LoadRewardedAd()
    {
        MaxSdk.LoadRewardedAd(VideoID[0]);
    }

    private void OnRewardedAdLoadedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
    {
        // Rewarded ad is ready for you to show. MaxSdk.IsRewardedAdReady(adUnitId) now returns 'true'.

        // Reset retry attempt
        retryAttemptRewarded = 0;
    }

    private void OnRewardedAdLoadFailedEvent(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
    {
        // Rewarded ad failed to load 
        // AppLovin recommends that you retry with exponentially higher delays, up to a maximum delay (in this case 64 seconds).

        retryAttemptRewarded++;
        double retryDelay = Math.Pow(2, Math.Min(6, retryAttemptRewarded));

        Invoke("LoadRewardedAd", (float)retryDelay);
    }

    private void OnRewardedAdDisplayedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo) { }

    private void OnRewardedAdFailedToDisplayEvent(string adUnitId, MaxSdkBase.ErrorInfo errorInfo, MaxSdkBase.AdInfo adInfo)
    {
        // Rewarded ad failed to display. AppLovin recommends that you load the next ad.
        LoadRewardedAd();
    }

    private void OnRewardedAdClickedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo) { }

    private void OnRewardedAdHiddenEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
    {
        // Rewarded ad is hidden. Pre-load the next ad
        LoadRewardedAd();
    }

    private void OnRewardedAdReceivedRewardEvent(string adUnitId, MaxSdk.Reward reward, MaxSdkBase.AdInfo adInfo)
    {
        if (click != null)
        {
            click();
        }
        // The rewarded ad displayed and the user should receive the reward.
    }

    private void OnRewardedAdRevenuePaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
    {
        // Ad revenue paid. Use this callback to track user revenue.
    }
#endif

    /// <summary>
    /// 展示视频广告
    /// </summary>
    /// <param name="_newPage">标签页</param>
    /// <param name="action">奖励回掉</param>
    /// <param name="action2">失败回掉</param>
    public void ShowRewardedAd(string eventName, object data)
    {
#if ADS_MAX
        click = (System.Action)data;

        isRewardAdded = false;
        if (MaxSdk.IsRewardedAdReady(VideoID))
        {
            AdOpenTime = 0;
            Debug.Log("Rewarded was loaded succesfully! " + VideoID);
            MaxSdk.ShowRewardedAd(VideoID);
        }else
        {
            Debug.Log("Rewarded Loding " + VideoID);
            
        }
#endif
    }

}

5、打包发布

由于unity2019,自带版本的gradle较低,跟sdk有冲突(需要升级gradle)

unity中会显示类似这些报错:

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.1.1/userguide/command_line_interface.html#sec:command_line_warnings
62 actionable tasks: 62 executed

android studio 中显示如下的错误:

 插件版本与所需gradle版本的关系

Android Gradle 插件版本说明  |  Android 开发者  |  Android Developers

解决方案:我这边用的是  插件版本4.1.1  gradle 版本6.5

方案1、unity中解决

Gradle Distributions 版本下载https://services.gradle.org/distributions/下载gradle-6.5-all.zip

下载完成后,我们需要把解压出来的gradle文件中的lib文件复制替换到你使用的unity对应位置,如D:\Program Files\2019.4.40f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle中的lib

 在发布设置中勾选 base gradle Template

将 Plugins 中Android 中的baseProjectTemplate 中 classpath 修改成  4.1.1(根据你下载gradle 版本对应的插件版本)

 方案2、导出安卓工程在 android studio 中设置版本

6、剩余问题(关于欧盟等其他地区隐私问题,目前也没搞懂放哪,有研究懂的兄弟可以回复我)

 

相关文章:

  • C#手动填充DataSet
  • coreutils5.0 uname命令和源码分析
  • OpenGL入门(四)之纹理Texture
  • UDP和TCP协议发送接收数据
  • Apache Doris 快速学习大纲
  • FastFlow(5)---软件加速器 software accelerator
  • 华为OD:0019-0020:-最小步骤数—删除字符串中出现次数最少的字符
  • Python学生成绩管信息理系统(面向对象)(学生信息篇)
  • 国稻种芯百团计划行动 丰收节贸促会·袁隆平:水稻国际竞争
  • 面试精选:3、史上最详细的Linux精选面试题(二)
  • 2.21 haas506 2.0开发教程 - TTS - Text To Speech (320开发板)
  • Promethues-如何监控容器
  • 测试人生 | 从小团队的业务到独角兽的测开,涨薪超过60%,90后小哥哥凤凰涅槃了
  • 技术门槛高?来看 Intel 机密计算技术在龙蜥社区的实践
  • 532. 数组中的 k-diff 数对
  • 【译】JS基础算法脚本:字符串结尾
  • JS 中的深拷贝与浅拷贝
  • CSS实用技巧
  • exports和module.exports
  • Java应用性能调优
  • JS变量作用域
  • js继承的实现方法
  • MySQL QA
  • mysql_config not found
  • Zepto.js源码学习之二
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 机器学习 vs. 深度学习
  • 简单实现一个textarea自适应高度
  • 将回调地狱按在地上摩擦的Promise
  • 问题之ssh中Host key verification failed的解决
  • 协程
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • #Ubuntu(修改root信息)
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (vue)页面文件上传获取:action地址
  • (搬运以学习)flask 上下文的实现
  • (二)丶RabbitMQ的六大核心
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (六)软件测试分工
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • .htaccess 强制https 单独排除某个目录
  • .NET : 在VS2008中计算代码度量值
  • .NET 5种线程安全集合
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .Net语言中的StringBuilder:入门到精通
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • @Autowired和@Resource的区别
  • @autowired注解作用_Spring Boot进阶教程——注解大全(建议收藏!)
  • [AR Foundation] 人脸检测的流程