Unity2019.2.9 安卓调用安装apk,安卓全版本适用

2020-03-12  本文已影响0人  Walk_In_Jar

安卓7的三星s7,redmi k20 pro 安卓10测试通过
找到了个老机器,安卓5.1的某为,安装后居然粉屏了,但等待一会后也弹出了安装界面,功能应该是没问题了。

首先确定包名,我用的是com.chengdu.sichuan。以免混淆。
apk地址在是qq的下载地址

https://qd.myapp.com/myapp/qqteam/QQ_JS/qqlite_4.0.0.1025_537062065.apk

备用。

Android Studio创建工程,详细步骤参考上一篇制作aar包教程

修改AndroidManife.xml
使用provider和添加一些权限


image.png

xml/filepaths的意思是在main/res目录下创建xml文件夹,创建filepaths.xml文件


image.png
完整filepaths.xml如下
<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external_storage_root"
        path="." />
    <files-path
        name="files-path"
        path="." />
    <cache-path
        name="cache-path"
        path="." />
    <!--/storage/emulated/0/Android/data/...-->
    <external-files-path
        name="external_file_path"
        path="." />
    <!--代表app 外部存储区域根目录下的文件 Context.getExternalCacheDir目录下的目录-->
    <external-cache-path
        name="external_cache_path"
        path="." />
    <!--配置root-path。这样子可以读取到sd卡和一些应用分身的目录,否则微信分身保存的图片,就会导致 java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/999/tencent/MicroMsg/WeiXin/export1544062754693.jpg,在小米6的手机上微信分身有这个crash,华为没有
-->
    <root-path
        name="root-path"
        path="" />
    </paths>

完整Androidmanife.xml如下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.chengdu.sichuan">

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:supportsRtl="true"
        >
        <activity android:name=".MainActivity">
            <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>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.chengdu.sichuan.fileprovider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>

    </application>

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.REPLACE_EXISTING_PACKAGE"/>
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
</manifest>

FileProvider报红的话,回到MainActivity.java

import androidx.core.content.FileProvider;

提供方法InstallApkUnity,参数是apk保存的路径


image.png

完整如下

package com.chengdu.sichuan;
//import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;
//import androidx.core.content.FileProvider;
import androidx.core.content.FileProvider;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
import java.io.File;
public class MainActivity extends UnityPlayerActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // setContentView(R.layout.activity_main);
    }
  public void InstallApkUnity(String apkPath){
      UnityPlayer.UnitySendMessage("_gameController", "CallUnity",  apkPath);
      //这一行的目的是调用unity的方法,可以不要
      File file = new File(apkPath);
      Intent intent = new Intent(Intent.ACTION_VIEW);
      if(Build.VERSION.SDK_INT>=24) { //Android 7.0及以上
          intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
          Uri apkUri = FileProvider.getUriForFile(getApplicationContext(), UnityPlayer.currentActivity.getPackageName() +".fileprovider", file);//记住修改包名
          //对目标应用临时授权该Uri所代表的文件
          intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
      }else{
          intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
          intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      }
      this.startActivity(intent);
  }
//显示提示信息
    public void ShowToast(final String msg){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(),msg,Toast.LENGTH_SHORT).show();
            }
        });
    }
}

androidx.core是安卓10相关的类库
按住Ctrl点击core,左边就会导航到这个文件

image.png

unity需要这个文件,右键Show in Explorer


image.png

这个文件备用。
Make Project 一下,找到到aar包与AndroidManifest.xml文件

新建unity工程,包名保持一致com.chengdu.sichuan

image.png

Plugins下创建Android/lib放入刚刚找到的classes.jar
放入aar包与AndroidManifest.xml文件
不要忘了打开aar文件,将里面的classes.jar里的BuildCongfig.class删除,关闭bandzip保存

image.png

创建Text用来显示内容


image.png

GameMama.cs内容如下

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
public class GameMana : MonoBehaviour
{
    HTTPDownLoad downLoad;
    AndroidJavaObject currentActivity;
    public Text text;
    private string action = "";
    private void Start()
    {
        if (Application.platform == RuntimePlatform.Android)
        {
            AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        }
        string s = "https://qd.myapp.com/myapp/qqteam/QQ_JS/qqlite_4.0.0.1025_537062065.apk";
        DownLoadFile(s);
    }
    public void DownLoadFile(string url)//下载指定文件
    {
        action = "";
        downLoad = new HTTPDownLoad(url, Application.persistentDataPath + "/download/", 5000);
        downLoad.loadedEvent = ((string fm) =>
        {
            action = fm;
            Debug.Log("  下载完成" + fm);
        });
    }
    private void Update()
    {
        if (!string.IsNullOrEmpty(action))
        {
             if (currentActivity != null)
                currentActivity.Call("InstallApkUnity", action);
            action = "";
        }
    }
    public void CallUnity(string s)
    {
        text.text = s;
    }
}

HTTPDownLoad.cs内容如下

using System;
using System.Net;
using System.IO;
using System.Threading;
using UnityEngine;
/// <summary>
/// 文件下载
/// </summary>
public class HTTPDownLoad
{
    public delegate void OnDownLoadedEvent(string fm);

    public OnDownLoadedEvent loadedEvent;

    private string postfix = ".temp";//临时文件后缀名
    // 下载进度
    public float Progress
    {
        get;
        private set;
    }
    // 状态 0 正在下载 1 下载完成 -1 下载出错
    public int Status
    {
        get;
        private set;
    }
    // 错误信息
    public string Error
    {
        get;
        set;
    }
    // 总长度
    public long TotalLength
    {
        get;
        private set;
    }
    // 保存路径
    private string savePath;
    // url地址
    private string url;
    // 超时时间
    private int timeout;
    // 子线程
    private Thread thread;
    // 子线程是否停止标志
    public bool isStop;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="url">url地址</param>
    /// <param name="timeout">超时时间</param>
    /// <param name="callback">回调函数</param>
    public HTTPDownLoad(string _url, string _savePath, int _timeout)
    {
        savePath = _savePath;
        url = _url;
        timeout = _timeout;
        DownLoad();
    }
    /// <summary>
    /// 开启下载
    /// </summary>
    void DownLoad()
    {
        Status = 0;
        isStop = false;

        // 开启线程下载
        thread = new Thread(StartDownLoad);
        thread.IsBackground = true;
        thread.Start();
    }
    public int poo = -1;
    /// <summary>
    /// 开始下载
    /// </summary>
    private void StartDownLoad()
    {

        try
        {
            if (!Directory.Exists(savePath))
            {
                Directory.CreateDirectory(savePath);
            }
            string fileName = url.Split('/')[url.Split('/').Length - 1];
            string pathName = savePath + "/" + ErasePostfix(fileName) + postfix;

            // 构建文件流
            FileStream fs = new FileStream(pathName, FileMode.OpenOrCreate, FileAccess.Write);
            // 文件当前长度
            long fileLength = fs.Length;
            // 文件总长度
            TotalLength = GetDownLoadFileSize();
            // Debug.LogFormat("fileLen:{0}", TotalLength);
            if (fileLength < TotalLength)
            {
                // 没有下载完成
                fs.Seek(fileLength, SeekOrigin.Begin);
                // 发送请求开始下载
                HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                request.AddRange((int)fileLength);
                request.Timeout = timeout;
                // 读取文件内容
                Stream stream = request.GetResponse().GetResponseStream();
                if (stream.CanTimeout)
                {
                    stream.ReadTimeout = timeout;
                }
                byte[] buff = new byte[4096];
                int len = -1;
                while ((len = stream.Read(buff, 0, buff.Length)) > 0)
                {
                    if (isStop)
                    {
                        break;
                    }
                    fs.Write(buff, 0, len);
                    fileLength += len;
                    Progress = fileLength * 1.0f / TotalLength;
                   // Debug.Log(Progress);
                }
                stream.Close();
                stream.Dispose();
            }
            else
            {
                Progress = 1;
            }
            fs.Close();
            fs.Dispose();
            // 标记下载完成
            if (Progress == 1)
            {
                Status = 1;
                
                string filepathName = savePath + "/" + fileName;
                
                if (File.Exists(filepathName))//删除原来的
                    File.Delete(filepathName);
                File.Move(pathName, filepathName);

                loadedEvent?.Invoke(filepathName);
            }
        }
        catch (Exception e)
        {
            Error = e.Message;
            Status = -1;
            Debug.Log(Error);
        }
    }
    /// <summary>
    /// 获取下载的文件大小
    /// </summary>
    /// <returns>文件大小</returns>
    public long GetDownLoadFileSize()
    {
        HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
        request.Method = "HEAD";
        request.Timeout = timeout;
        HttpWebResponse response = request.GetResponse() as HttpWebResponse;
        return response.ContentLength;
    }
    /// <summary>
    /// 停止下载
    /// </summary>
    public void Close()
    {
        isStop = true;
    }
    private string ErasePostfix(string filePath)
    {
        return filePath.Substring(0, filePath.LastIndexOf('.'));
    }
}
image.png

下载完成后会调用InstallApkUnity方法来安装,安卓10验证通过。
安卓调用unity中的方法

    public void CallUnity(string s)
    {
        text.text = s;
    }
image.png

不要忘了在other Setting中设置读写外部存储


image.png

完整的安卓工程与unity资源包如下地址

链接:https://pan.baidu.com/s/106HfAKDCMj0ABPCLtDD2-g
提取码:3zt0

上一篇下一篇

猜你喜欢

热点阅读