Unity2022接入Google广告与支付SDK、导出工程到Android Studio使用JDK17进行打包完整流程与过程中的相关错误及处理经验总结

注:因为本人也是第一次接入广告与支付SDK相关的操作,网上也查了很多教程,很多也都是只言片语或者缺少一些关键步骤的说明,导致本人也是花了很多时间与精力踩了很多的坑才搞定,发出来也是希望能帮助到其他人在遇到相似问题的时候能少踩坑少熬夜少加班,至少能提供一个解决问题的思路,理论上该经验可适用于任意版本的SDK接入,总归思路都是差不多的,文章内容可能会不定期修改,如果存在不准确或理解错误的地方,可评论区通知我进行修改

注意翻墙问题,毕竟国内对于国外的网站很多是没办法进行访问的。
文章中所使用的各软件及插件版本说明(可能存在遗留的地方,可能后期修改补档吧,大部分通用没问题大概率不会改了)

Unity:2022.3.15

Unity所使用的 Google SDK:9.0.0(一开始使用的8.5版本,结果刚好弄完的时候该版本弃用了,只能换成了9.0.0,但9.0中所使用的SDK版本是23版本的,23版本需要JDK17与Gradle8.0才能编译,所以只能导出到Android Studio进行编译)

Google Play 支付采用的是接入原生支付进行操作的,版本为6.0,文章中主要包含一些经验总结,因为思路总体也是参考了其他人的文章

1、广告SDK接入

Google SDK获取地址:Google 广告 SDK Mobile Ads SDK (Unity)

需要关注的点:

1、广告SDK弃用时间,相关链接:弃用和停用 | Unity | Google for Developers ,注意其中的版本信息对应的是Android原生SDK的版本信息,新手注意别搞混了,Unity所使用的插件中的版本信息需要从Github中对应版本的日志中进行查看

2、Android Gradle插件可使用的Gradle版本,相关链接:Android Gradle 插件 8.7 版本说明 | Android Studio | Android Developers,注意让看这个主要是为了后边使用Android Studio进行编译的时候,知道该用那个版本进行编译

3、广告SDK接入流程并不复杂,心平气和看完操作步骤就可以搞定,别像我一样的因为加班太多太过浮躁导致简单的问题复杂化,所以具体接入步骤不做详细说明,根据SDK获取的界面中按照官方的步骤进行接入即可,需注意的关注的是,SDK所使用的JDK版本、Gradle版本是否与当前Unity版本是否兼容, 例如本人使用的是Unity2022.3.15+广告SDK的9.0版本,而Unity2022没有办法更换使用JDK17(至少我没找到办法),所以需要导出到Android Studio进行打包操作

4、打包时google Setting中的应用id一定要填写,不填写的话,就算打包成功了,进行安装后同样也会因为ID未找到从而无法成功运行应用

5、接入的SDK版本较低时,SDK被弃用后,可以在安卓日志中看到Google的通知,广告不会正常播放,效果就是点击后没有任何效果

6、成功接入广告并打包后,正常情况下就可以看到广告的内容

7、播放广告后的奖励回调函数,记得一定使用协程进行操作,也就说传入的回调函数可以是普通函数,但关于传入的回调函数的最终执行时一定使用一个协程去运行, 因为直接进行调用,会导致应用直接就给闪退了

关于广告的部分就先到这里,因为广告的接入不难,难点都在打包的过程中了

2、原生支付SDK接入

接入原生支付后(也就是加入jar包后),需要打包后才能看到效果在编辑器中是没有办法看到效果的

先说明一下思路来源相关链接:

Unity接入GooglePlay内购V4 V5 V6(源生Android方式)_unity接入google内购-CSDN博客

后台UnityPlayer.UnitySendMessage不生效(Android) | 梓喵出没

第一个链接为参考原生支付接入的方法,而第二个则是对UnityPlayer.UnitySendMessage调用一次后再次进行调用时,没有任何反应的处理,至于为什么没有反应,简单来说就是被sendMessage调用的函数代码所在的activity需要保持在前台,一旦被切换为其他activity后,再次调用代码就没有什么效果了,我解释的可能太过笼统或者不正确,详细的解释请自行百度吧,或者遇到了的时候自然就懂了,所以这里推荐对于Unity内部方法的调用采用第二个链接中的方法,直接一劳永逸,即编写一个C#脚本继承AndroidJavaProxy类,用于实现Java代码中的接口,在初始化java对象时,new一个实现了Java接口函数的类同时传递给java对象,并保存一下对对象的引用,然后呢,直接把收到的对象当成一个接口使用就好了例如下边实现

C#代码:

代码只有部分啊,别全抄了,只是做参考,因为该代码也只是对第一个链接中的代码修改后得到的

cs 复制代码
public class IAPMessage : AndroidJavaProxy
    {
        public IAPMessage() : base("com.XXX.unitytogoolgleplaylib.IAPMessage")
        {
        }

        #region callback from Objective-c/JAR
        //获取到产品列表回调
        public void RecieveProductInfos(string jsonData)
        {
            if (string.IsNullOrEmpty(jsonData)) return;
            var infoData = JsonConvert.DeserializeObject<IAPProductInfoData>(jsonData);
            OnProductInfoReceived(infoData);
        }

        //产品列表请求失败
        public void ProductRequestFail(string message)
        {
            OnProductInfoFail(message);
        }

        //购买成功回调
        public void ProductBuyComplete(string productId)
        {
            OnProductBuyComplete(productId);
        }

        //购买失败回调
        public void ProductBuyFailed(string jsonData)
        {
            var infoData = JsonConvert.DeserializeObject<BuyFailData>(jsonData);
            OnBuyProductFail(infoData.productId, infoData.error);
        }

        //获取商品回执回调
        public void ProvideContent(string msg) { }

        //购买取消回调
        public void ProductBuyCancled(string productId)
        {
            OnBuyProductCancled(productId);
        }

        /// <summary>
        /// 恢复购买成功
        /// </summary>
        /// <param name="productId"></param>
        public void RestoreComplete(string productId)
        {
            OnRestoreCompleted(productId);
        }

        public void ConnectTips()
        {
            Debug.LogWarning("Java Connect!");
        }

        public void ConnectTips1(string str)
        {
            Debug.LogWarning($"Java Connect Test {str}!");
        }

        private void ClearCallback()
        {
            ProductBuyFailedCallback = null;
            ProductBuyCompleteCallback = null;
            ProductBuyCancledCallback = null;
        }
        #endregion

        //接收到产品信息
        void OnProductInfoReceived(IAPProductInfoData info)
        {
            Debug.Log("[IAPMessage]Unity接收到商品信息:" + info.ToString());
            SDKGuanLiQi.SetInitShopState(true);
        }

        //接收到产品信息
        void OnProductInfoFail(string error)
        {
            Debug.Log("[IAPMessage]Unity商品信息请求失败:" + error);
            SDKGuanLiQi.SetInitShopState(false);
        }

        //购买完成
        void OnProductBuyComplete(string productId)
        {
            Debug.Log("[IAPMessage]购买完成" + productId);
            ProductBuyCompleteCallback?.Invoke();
            ClearCallback();
        }

        //购买失败
        void OnBuyProductFail(string productId, string error)
        {
            Debug.Log(string.Format("[IAPMessage]购买失败:{0} 错误信息{1}", productId, error));
            ProductBuyFailedCallback?.Invoke();
            ClearCallback();
        }

        //购买取消
        void OnBuyProductCancled(string productId)
        {
            Debug.Log("[IAPMessage]购买取消" + productId);
            ProductBuyCancledCallback?.Invoke();
            ClearCallback();
        }

        //恢复完成
        void OnRestoreCompleted(string productId)
        {
        }
    }

Java代码:

java 复制代码
package com.XXX.unitytogoolgleplaylib;

// 与C#交互的接口
public interface IAPMessage
{
    //获取到产品列表回调
    public void RecieveProductInfos(String jsonData);

    //产品列表请求失败
    public void ProductRequestFail(String message);

    //购买成功回调
    public void ProductBuyComplete(String productId);

    //购买失败回调
    public void ProductBuyFailed(String jsonData);

    //获取商品回执回调
    public void ProvideContent(String msg);

    //购买取消回调
    public void ProductBuyCancled(String productId);

    /// <summary>
    /// 恢复购买成功
    /// </summary>
    /// <param name="productId"></param>
    public void RestoreComplete(String productId);
}

然后调用时赋值的方式参考图:

第一张图为Android Studio中的项目截图,第二张则是C#代码截图,演示一下的,没什么难度一试便会了,很简单

但需要注意的是接入的com.android.billingclient版本与JDK版本兼容性的问题,推荐接入6.0.1,因为本人接入的就是这个版本的,下面再附加上一张我的模块的build.gradle配置图

同时构建完成后jar包可在下图中的路径下边找到,就不用去解压aar包了,毕竟每次都去解压比较麻烦

这里补档说明一下, 因为是对支付模块的单独构建打包,在构建时可能会因为插件中所需要使用的其他插件的版本问题而导致构建失败,出现这些问题的时候,可以在下图中修改一下所使用的Gradle版本和其他模块的版本,修改为你构建时所需要的版本,同样的图中的内容仅作参考:

因为我使用的Android Studio版本是2024.2.1版本的,所以使用其他版本的配置方式可能存在一些细节上的不同

3、导出工程后再Android Studio中进行构建

这里是大头,因为这里边的坑才是最多的,导出的方法不做详细解释,只对使用Android Studio打开导出的项目包后的操作进行说明

1、修改Gradle版本

这里需要修改的为编译时使用的Gradle版本与Android Gradle 插件版本,修改编译时的Gradle版本路径如下图,直接修改配置文件中的版本号就好了,至于需要修改为那个版本,就需要查看Android Gradle插件版本所需要的版本了

修改Android Gradle插件版本,看下边截图了,也是直接修改版本号就行了:

修改Gradle方法(同时也是修改JDK、NDK的操作步骤之一)还有一个就是如下图,按照截图顺序操作修改为所需要的版本后应用一下就好了:

2、为build.gradle配置文件添加命名空间名称 namespace "com.XXX.XXX"

如下图,下图为unityLibary下的build.gradle配置文件添加命名空间,注意命名空间名称只能为namespace "com.unity3d.player",改成其他的都会出问题,然后记得删得NDK的配置路径,因为可能你所使用的插件所需的最低NDK版本比Unity所提供的NDK版本高,反正删了少一堆问题就对了,里边使用的JavaVersion版本也随手改一下,避免使用Android Studio修改Java 版本的时候,没有修改到的情况出现

删掉或者注释掉下图中框起来的部分可以加快打包的时间,之前百度优化包体时看到的其他的解释是,去掉再次进行il2cpp的编译过程还是什么的是,反正删掉了不影响编译结果,出现其他问题的话,再次加回来再次编译就行了

然后在其他的build.gradle文件中找到android {......}的内容块,并在android{.....}块中的第一行加入命名空间 namespace "这里修改为你的应用的包名",例如下图,包名可在下面第二张图中找到

3、修改JDK、NDK、Build Tools版本等

打开Project Structur窗口,操作步骤参考上方修改Gradle版本的第二个方法,然后根据下图中框选的部分,修改所需要的SDK、JDK、NDK、Build Tools等的版本后应用保存一下,如果没有所需要的版本的话,可以在File-》Settings打开Settings窗口后,看下边第二张图

没错就是这张图,注意如果要通过修改配置文件的方式配置修改Gradle版本版本的话,记得下图中的Distribution的配置就不要进行修改

然后SDK、NDK、Build Tools的安装看这张图,记得勾选右下角的show package details选项看到更多的内容

4、修改所有能找到的AndroidManifest.xml文件,注意是所有(主要是为了减小打包后的包体大小,不介意包体大小的可以不改)

在application后边加上android:extractNativeLibs="true"参考下图

如果已经存在android:extractNativeLibs配置并且为false,就修改为true,添加这段的具体原因则是为了启用压缩功能,详情自行百度,毕竟本人也不是做安卓开发的这段也只是搜索优化时偶然看到的

5、修改settings.gradle文件,如下图,非必要步骤

其实就是使用Unity原本的配置就好了,添加上这一步的主要原因是为了避免因为将maven仓库的源修改为使用国内镜像时,导致一些jar包下载搜索不到的问题,毕竟接入的是google的SDK,翻墙都没问题了,使用原本的配置也就不会出现对下载速度造成影响的问题了

结语

好了,恭喜你完成以上步骤后就可以同步一下然后进行apk的构建了,其中可能因为省略了一些步骤看着会比较迷茫,后期我不定时改改吧,因为连续加班也是弄得脑袋不舒服,详细步骤需要关注的点也可能少了一些,不过还是欢迎留言,看到了也都会第一时间进行回复的

最后2025年1月1日,元旦节快乐

祝大家都能拥有幸福开心满意的工作,并且每天都能不加班可以多陪陪家人

相关推荐
还鮟1 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡2 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi002 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体
Zlzxzw3 小时前
使用unity创建项目,进行动画制作
unity·游戏引擎
zhangphil4 小时前
Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值
android
你过来啊你4 小时前
Android View的绘制原理详解
android
移动开发者1号7 小时前
使用 Android App Bundle 极致压缩应用体积
android·kotlin
移动开发者1号7 小时前
构建高可用线上性能监控体系:从原理到实战
android·kotlin
X_StarX7 小时前
【Unity笔记01】基于单例模式的简单UI框架
笔记·ui·unity·单例模式·游戏引擎·游戏开发·大学生
九班长7 小时前
Golang服务端处理Unity 3D游戏地图与碰撞的详细实现
3d·unity·golang