1. Android
1.1 安装Android Studio
过程略。
1.2 新建安卓工程


记住自己的Package name。
然后在编辑器左上角,切换模式为Project,如下图:

1.3 新建Module
在工程中新建一个Module,取名为如下图:



1.4 功能代码
接着找到新建的Module,然后在Src—>Main—>java—>com.nofun.install
文件夹下新建两个Class,见下图:

脚本代码如下:
package com.nofun.install;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class InitializeApkBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())){
InstallApkUtils.removeApkFile(InstallApkUtils.apkFilePath);
}
if(Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())){
}
if(Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())){
}
}
}
package com.nofun.install;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Build;
import androidx.core.content.FileProvider;
import java.io.File;
public class InstallApkUtils {
private Context mContext;
private static InstallApkUtils mInstallApkUtils = null;
private InitializeApkBroadcastReceiver apkBroadcastReceiver;
public static String apkFilePath;
public InstallApkUtils(Context context) {
this.mContext = context;
}
public static InstallApkUtils getInstance(Context context){
if (mInstallApkUtils == null) {
mInstallApkUtils = new InstallApkUtils(context);
}
return mInstallApkUtils;
}
//安装Apk
public void installApk(String filePath){
apkFilePath = filePath;
File apkFile = new File(filePath);
if(!apkFile.exists()){
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){//安卓7.0以上
Uri apkUri = FileProvider.getUriForFile(mContext,mContext.getPackageName() + ".fileProvider",apkFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri,"application/vnd.android.package-archive");
}
else {//安卓7.0以下
intent.setDataAndType(Uri.parse("file://" + apkFile.toString()),"application/vnd.android.package-archive");
}
if(mContext.getPackageManager().queryIntentActivities(intent,0).size() > 0){
mContext.startActivity(intent);
}
}
//注册广播
public void registerBroadcast(){
if(apkBroadcastReceiver == null){
apkBroadcastReceiver = new InitializeApkBroadcastReceiver();
}
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
intentFilter.addDataScheme("package");
mContext.registerReceiver(apkBroadcastReceiver,intentFilter);
}
//取消注册广播
public void unregisterBroadcast(){
if(apkBroadcastReceiver != null){
mContext.unregisterReceiver(apkBroadcastReceiver);
apkBroadcastReceiver = null;
}
}
//删除apk文件
public static void removeApkFile(String path){
File apkFile = new File(path);
if(apkFile.isFile() && apkFile.exists()){
apkFile.delete();
}
}
}
1.5 修改AndroidManifest.xml
注意,是Module下面的AndroidManifest,不是工程中的:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nofun.install">
<uses-permission android:name="android.permission.REPLACE_EXISTING_PACKAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<application>
<meta-data
android:name="com.google.android.actions"
android:resource="@xml/provider_paths" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
</manifest>
1.6 新建provider_paths.xml

也是在Module下面新建,目录结果如上,如果没有xml文件夹,就新建这个文件夹。
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="publicDir" path="." />
</paths>
1.7 Build

点击"Make Project
"进行构建,完成后在Module的build—>outputs—>aar文件夹下就能看到生成的aar文件了。
2.Unity
2.1 添加aar
将上面生成的aar文件放到Unity的Plugins/Android
文件夹中。
2.2 调用脚本
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class ApplicationStoreManager : MonoBehaviour
{
private AndroidJavaObject installApkUtils;
// Start is called before the first frame update
void Start()
{
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaClass installApkUtilsClass = new AndroidJavaClass("com.nofun.install.InstallApkUtils");
installApkUtils = installApkUtilsClass.CallStatic<AndroidJavaObject>("getInstance", currentActivity);
installApkUtils.Call("registerBroadcast");
}
private void OnDestroy()
{
installApkUtils.Call("unregisterBroadcast");
}
/// <summary>
/// 安装Apk
/// </summary>
/// <param name="filePath"> Apk文件路径 </param>
public void InstallApk(string filePath)
{
installApkUtils.Call("installApk", filePath);
}
}
2.3 工程设置
2.3.1 Publishing Settings
在Publishing Settings勾选下图的选项:

2.3.2 修改配置文件
上面两个选项勾选后,会在Asset—>Plugins—>Android
文件夹中生成gradleTemplate.properties和mainTemplate.gradle两个文件,需要分别修改这两个文件。
mainTemplate.gradle,在dependencies 块中添加一行代码:
implementation 'androidx.appcompat:appcompat:1.2.0'
gradleTemplate.properties,在文件最后面添加以下内容:
android.overridePathCheck=true
android.useAndroidX=true
android.enableJetifier=true
2.4 打包
接着在Unity中打包即可,亲测2021版本有效。