Unity Android交互自动安装更新

开始做一个安卓小游戏,没有想到要去热更新它,结果做完才想到,有bug怎么办…

于是就有了下面的踩坑之旅。

版本环境

  • Unity 2020.3.20f1c1
  • Android Studio 4.1.3

踩坑之旅

Unity调用Android的方法
  1. 新建一个Empty Activity项目

    Unity Android交互自动安装更新_第1张图片

    Unity Android交互自动安装更新_第2张图片

  2. 点击完成后,删除红框内容无用内容

    Unity Android交互自动安装更新_第3张图片

    Unity Android交互自动安装更新_第4张图片

    变更后的AndroidManifest.xml文件

    
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="cn.linyisonger.callme">
    
        <application >
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                intent-filter>
            activity>
        application>
    manifest>
    
  3. 添加一个测试的静态方法

    Unity Android交互自动安装更新_第5张图片

  4. 修改继承自Activity

    Unity Android交互自动安装更新_第6张图片

  5. 修改构建文件

    Unity Android交互自动安装更新_第7张图片

  6. 构建arr包

    Unity Android交互自动安装更新_第8张图片

  7. 新建一个Unity工程

    Unity Android交互自动安装更新_第9张图片

  8. Build Settings… Ctrl+Shift+B

    Unity Android交互自动安装更新_第10张图片

    切换至Android平台

  9. 将生成好的arr包放入Plugins\Android目录下

    Unity Android交互自动安装更新_第11张图片

  10. 新建脚本调用它

    Unity Android交互自动安装更新_第12张图片

    新建Test脚本文件

    using UnityEngine;
    using UnityEngine.UI;
    
    public class Test : MonoBehaviour
    {
        public Text showResult;
    
        private void Start()
        {
            var jo = new AndroidJavaObject("cn.linyisonger.android.MainActivity");
            int sum = jo.CallStatic<int>("add", 1, 3);
            showResult.text = sum.ToString();
        }
    }
    

    新建一个Text随便改改样式、将脚本挂在Canvas上(当然挂在那里都是可以的,我就随便挂一下)、将Text组件拖至脚本的showResult字段上。

  11. 打包测试

    Unity Android交互自动安装更新_第13张图片

    添加场景、选择运行设备、构建并运行

  12. 效果

    Unity Android交互自动安装更新_第14张图片

Unity自动更新并调用安装

示意图 有点糙

Unity Android交互自动安装更新_第15张图片

  1. classes.jar包引入项目中来D:\Unity\2020.3.20f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes

    Unity Android交互自动安装更新_第16张图片

    右键添加类库

    Unity Android交互自动安装更新_第17张图片

  2. 将classes.jar设置为仅编译时构建,打包时不包含此文件(Unity打包会带上)

    implementation files('libs\\classes.jar') // 当前
    compileOnly fileTree(dir: "libs",includes: ["*.jar"]) // 修改
    

    Unity Android交互自动安装更新_第18张图片

  3. 添加安装方法

    MainActivity.java

    package cn.linyisonger.callme;
     
    import androidx.core.content.FileProvider;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Bundle;
    
    import com.unity3d.player.UnityPlayer;
    
    import java.io.File;
    
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        public static int add(int a, int b) {
            return a + b;
        }
    
        public static void install(String apkFullPath){
            Intent intent = new Intent(Intent.ACTION_VIEW);
            File file = new File(apkFullPath);
            if (Build.VERSION.SDK_INT >= 24) {
                Uri apkUri = FileProvider.getUriForFile(UnityPlayer.currentActivity.getApplicationContext(), UnityPlayer.currentActivity.getPackageName() +".fileprovider", file);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
            } else {
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                Uri uri = Uri.fromFile(file);
                intent.setDataAndType(uri, "application/vnd.android.package-archive");
            }
            UnityPlayer.currentActivity.startActivity(intent);
        }
    
    }
    
  4. 构建arr包放置在Unity工程中

  5. 设置包名

    Unity Android交互自动安装更新_第19张图片

  6. 添加filepaths.xml文件,放在Android/res/xml下

    
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="download" path="Android/data/cn.LinYisonger.CallAndroid/files/"/>
    paths>
    

    Unity Android交互自动安装更新_第20张图片

  7. 添加AndroidManifest.xml文件,放在Android下

    
    
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player"
        xmlns:tools="http://schemas.android.com/tools">
        
        <uses-permission android:name="android.permission.INTERNET">uses-permission>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
        <uses-permission android:name="android.permission.CALL_PHONE"/>
        <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    
    
    
        <application>
            <provider android:name="androidx.core.content.FileProvider" android:authorities="cn.LinYisonger.CallAndroid.fileprovider" android:grantUriPermissions="true" android:exported="false" android:usesCleartextTraffic="true">
                <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" />
            provider>
            <activity android:name="com.unity3d.player.UnityPlayerActivity" android:theme="@style/UnityThemeSelector">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                intent-filter>
                <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
            activity>
        application>
    manifest>
    
  8. 添加更新脚本

    using System;
    using System.Collections;
    using System.IO;
    using UnityEngine;
    using UnityEngine.Networking;
    using UnityEngine.UI;
    
    public class Test1 : MonoBehaviour
    {
    
        /// 
        /// 版本模型
        ///  
        public class VersionModel
        {
            /// 
            /// Id
            /// 
            public long id;
            /// 
            /// 程序Key值
            /// 
            public string key;
            /// 
            /// 编号
            /// 
            public string no;
            /// 
            /// 描述
            /// 
            public string desc;
            /// 
            ///  安卓包路径
            /// 
            public string apkUrl;
        }
        public delegate void LoadingAction(float progress);
        public delegate void VersionAction(VersionModel version);
        private VersionModel CurrentVersion;
    
        private string path => Application.persistentDataPath + "/update.apk";
    
        public Text UpdateText;
    
    
        private void Start()
        {
            StartCoroutine(GetCurrentVersion((v) =>
            {
                if (v.no != Application.version)
                {
                    StartCoroutine(Download((p) =>
                    {
                        // 下载进度
                        UpdateText.text = (p * 100).ToString("0.00");
                    },
                    () =>
                    {
                        // 下载完成
                        UpdateText.text = "下载完成";
                        // 安装
                        Install();
                    }));
                }
            }));
    
    
    
        }
    
        public IEnumerator GetCurrentVersion(VersionAction action)
        {
            UnityWebRequest webRequest = UnityWebRequest.Get("http://y.linyisonger.cn/api/version/GetTheLatestVersion?key=cn.LinYisonger.CallAndroid");
            yield return webRequest.SendWebRequest();
            CurrentVersion = JsonUtility.FromJson<VersionModel>(webRequest.downloadHandler.text);
            action.Invoke(CurrentVersion);
        }
        public IEnumerator Download(LoadingAction loading, Action done)
        {
            UnityWebRequest webRequest = UnityWebRequest.Get(CurrentVersion.apkUrl);
            webRequest.SendWebRequest();
            while (!webRequest.isDone)
            {
                loading(webRequest.downloadProgress);
                yield return 0;
            }
            File.WriteAllBytes(path, webRequest.downloadHandler.data);
            done();
            yield return null;
        }
        public void Install()
        {
            var jo = new AndroidJavaObject("cn.linyisonger.callme.MainActivity");
            jo.CallStatic("install", path);
        }
    }
    

    Unity Android交互自动安装更新_第21张图片

  9. 构建调试然后就会报错

    WARNING: The option setting 'android.enableR8=false' is deprecated.
    It will be removed in version 5.0 of the Android Gradle plugin.
    You will no longer be able to disable R8
    

    Unity Android交互自动安装更新_第22张图片

    将构建的版本调整为3.4.0

    Unity Android交互自动安装更新_第23张图片

  10. 构建调试打开应用闪退啦!

    找了很久原来是少引用了依赖库

    Unity Android交互自动安装更新_第24张图片

    # 添加依赖支持
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    

    Unity Android交互自动安装更新_第25张图片

  11. 构建调试

参考文章

  • https://blog.csdn.net/wodownload2/article/details/118081593
  • https://www.jianshu.com/p/a6cad97ea54f
  • https://www.cnblogs.com/wuzhang/p/wuzhang20190405.html
  • https://blog.csdn.net/zhangjinlong1234/article/details/108569607

你可能感兴趣的:(Unity3D,unity,android,游戏引擎)