如何从统一代码安装Android APK

编程入门 行业动态 更新时间:2024-10-16 22:20:16
本文介绍了如何从统一代码安装Android APK的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我找到了Java的代码段.如何在C#Unity中编写这样的代码?

I found snippet for Java. How can I write such a code in C# Unity?

Intent intent = new Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(Uri.fromFile(new File("link to downloaded file")),"application/vnd.android.package-archive"); startActivity(intent);

推荐答案

您可以构建一个jar/aar插件,然后从C#中调用它.这更容易做到.

You can build a jar/aar plugin and call it from C#. That's more easier to do.

另一种解决方案是使用AndroidJavaObject和AndroidJavaClass直接在没有插件的情况下执行此操作.用AndroidJavaObject和AndroidJavaClass进行此操作需要大量测试才能正确完成.以下是我用来执行此操作的方法.它会先下载一个APK,然后再安装它.

Another solution is to use AndroidJavaObject and AndroidJavaClass to do this directly without a plugin. Doing it with AndroidJavaObject and AndroidJavaClass requires lots of testing to get it right. Below is what I use to do that. It downloads an APK then installs it.

首先创建一个名为"TextDebug" 的UI文本,以便您可以看到在下载/安装过程中发生了什么.如果不这样做,则必须注释掉或删除所有GameObject.Find("TextDebug").GetComponent<Text>().text...代码行.

First of all create a UI text called "TextDebug" so it you will see what's going on during the download/install. If you don't do this you must comment out or remove all the GameObject.Find("TextDebug").GetComponent<Text>().text... line of code.

void Start() { StartCoroutine(downLoadFromServer()); } IEnumerator downLoadFromServer() { string url = "apkdl.androidapp.baidu/public/uploads/store_2/f/f/a/ffaca37aaaa481003d74725273c98122.apk?xcode=854e44a4b7e568a02e713d7b0af430a9136d9c32afca4339&filename=unity-remote-4.apk"; string savePath = Path.Combine(Application.persistentDataPath, "data"); savePath = Path.Combine(savePath, "AntiOvr.apk"); Dictionary<string, string> header = new Dictionary<string, string>(); string userAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"; header.Add("User-Agent", userAgent); WWW www = new WWW(url, null, header); while (!www.isDone) { //Must yield below/wait for a frame GameObject.Find("TextDebug").GetComponent<Text>().text = "Stat: " + www.progress; yield return null; } byte[] yourBytes = www.bytes; GameObject.Find("TextDebug").GetComponent<Text>().text = "Done downloading. Size: " + yourBytes.Length; //Create Directory if it does not exist if (!Directory.Exists(Path.GetDirectoryName(savePath))) { Directory.CreateDirectory(Path.GetDirectoryName(savePath)); GameObject.Find("TextDebug").GetComponent<Text>().text = "Created Dir"; } try { //Now Save it System.IO.File.WriteAllBytes(savePath, yourBytes); Debug.Log("Saved Data to: " + savePath.Replace("/", "\\")); GameObject.Find("TextDebug").GetComponent<Text>().text = "Saved Data"; } catch (Exception e) { Debug.LogWarning("Failed To Save Data to: " + savePath.Replace("/", "\\")); Debug.LogWarning("Error: " + e.Message); GameObject.Find("TextDebug").GetComponent<Text>().text = "Error Saving Data"; } //Install APK installApp(savePath); } public bool installApp(string apkPath) { try { AndroidJavaClass intentObj = new AndroidJavaClass("android.content.Intent"); string ACTION_VIEW = intentObj.GetStatic<string>("ACTION_VIEW"); int FLAG_ACTIVITY_NEW_TASK = intentObj.GetStatic<int>("FLAG_ACTIVITY_NEW_TASK"); AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent", ACTION_VIEW); AndroidJavaObject fileObj = new AndroidJavaObject("java.io.File", apkPath); AndroidJavaClass uriObj = new AndroidJavaClass("android.Uri"); AndroidJavaObject uri = uriObj.CallStatic<AndroidJavaObject>("fromFile", fileObj); intent.Call<AndroidJavaObject>("setDataAndType", uri, "application/vnd.android.package-archive"); intent.Call<AndroidJavaObject>("addFlags", FLAG_ACTIVITY_NEW_TASK); intent.Call<AndroidJavaObject>("setClassName", "com.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity"); AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); currentActivity.Call("startActivity", intent); GameObject.Find("TextDebug").GetComponent<Text>().text = "Success"; return true; } catch (System.Exception e) { GameObject.Find("TextDebug").GetComponent<Text>().text = "Error: " + e.Message; return false; } }

对于 Android API 24 及更高版本,由于API发生了更改,因此需要使用不同的代码.以下C#代码基于此 Java答案.

For Android API 24 and above, this requires a different code since the API changed. The C# code below is based on the this Java answer.

//For API 24 and above private bool installApp(string apkPath) { bool success = true; GameObject.Find("TextDebug").GetComponent<Text>().text = "Installing App"; try { //Get Activity then Context AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); AndroidJavaObject unityContext = currentActivity.Call<AndroidJavaObject>("getApplicationContext"); //Get the package Name string packageName = unityContext.Call<string>("getPackageName"); string authority = packageName + ".fileprovider"; AndroidJavaClass intentObj = new AndroidJavaClass("android.content.Intent"); string ACTION_VIEW = intentObj.GetStatic<string>("ACTION_VIEW"); AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent", ACTION_VIEW); int FLAG_ACTIVITY_NEW_TASK = intentObj.GetStatic<int>("FLAG_ACTIVITY_NEW_TASK"); int FLAG_GRANT_READ_URI_PERMISSION = intentObj.GetStatic<int>("FLAG_GRANT_READ_URI_PERMISSION"); //File fileObj = new File(String pathname); AndroidJavaObject fileObj = new AndroidJavaObject("java.io.File", apkPath); //FileProvider object that will be used to call it static function AndroidJavaClass fileProvider = new AndroidJavaClass("android.support.v4.content.FileProvider"); //getUriForFile(Context context, String authority, File file) AndroidJavaObject uri = fileProvider.CallStatic<AndroidJavaObject>("getUriForFile", unityContext, authority, fileObj); intent.Call<AndroidJavaObject>("setDataAndType", uri, "application/vnd.android.package-archive"); intent.Call<AndroidJavaObject>("addFlags", FLAG_ACTIVITY_NEW_TASK); intent.Call<AndroidJavaObject>("addFlags", FLAG_GRANT_READ_URI_PERMISSION); currentActivity.Call("startActivity", intent); GameObject.Find("TextDebug").GetComponent<Text>().text = "Success"; } catch (System.Exception e) { GameObject.Find("TextDebug").GetComponent<Text>().text = "Error: " + e.Message; success = false; } return success; }

如果出现异常:

尝试调用虚拟方法 'android.content.res.XmlResourceParser android.content.pm.packageItemInfo.loadXmlMetaData(android.c‌ontent.pm.PackageMan‌ager.java.lang.Strin‌g)'

Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.packageItemInfo.loadXmlMetaData(android.c‌​ontent.pm.PackageMan‌​ager.java.lang.Strin‌​g)'

您必须要做的几件事.

1 .从您的"AndroidSDK/extras/android/support/v4/android-support-v4.jar"中复制"android-support-v4.jar" 目录到您的"UnityProject/Assets/Plugins/Android" 目录.

1.Copy "android-support-v4.jar" from your "AndroidSDK/extras/android/support/v4/android-support-v4.jar" directory to your "UnityProject/Assets/Plugins/Android" directory.

2 .在 UnityProject/Assets/Plugins/Android 目录中创建一个名为"AndroidManifest.xml"的文件,并将下面的代码放入其中.

2.Create a file called "AndroidManifest.xml" in your UnityProject/Assets/Plugins/Android directory and put the code below into it.

请确保将"company.product" 替换为您自己的程序包名称.出现了 2 个实例.您必须同时替换它们:

Make sure to replace "company.product" with your own package name. There are 2 instances where this appeared. You must replace both of them:

可在 package ="company.product" 和 android:authorities ="company.product.fileprovider" 中找到.不要更改或删除文件提供程序" ,也不要更改其他任何内容.

These are found in package="company.product" and android:authorities="company.product.fileprovider". Don't change or remove the "fileprovider" and don't change anything else.

这是"AndroidManifest.xml"文件:

Here is the "AndroidManifest.xml" file:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="schemas.android/apk/res/android" package="company.product" xmlns:tools="schemas.android/tools" android:installLocation="preferExternal" android:versionName="1.0" android:versionCode="1"> <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" /> <application android:theme="@style/UnityThemeSelector" android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="true"> <activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name"> <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="android.support.v4.content.FileProvider" android:authorities="company.product.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/> </provider> </application> <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" /> </manifest>

3 .在"UnityProject/资产/插件/Android/res/xml"中创建一个名为" provider_paths.xml "的新文件 >目录,并将代码放在下面.如您所见,您必须先创建一个 res 文件夹,然后创建一个 xml 文件夹.

3.Create a new file called "provider_paths.xml" in your "UnityProject/Assets/Plugins/Android/res/xml" directory and put the code below in it. As you can see, you have to create a res and then an xml folder.

请确保将"company.product" 替换为您自己的程序包名称. 它只会一次出现.

Make sure to replace "company.product" with your own package name. It only appeared once.

这是您应放入此" provider_paths.xml "文件中的内容:

Here is what you should put into this "provider_paths.xml" file:

<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="schemas.android/apk/res/android"> <!--<external-path name="external_files" path="."/>--> <external-path path="Android/data/company.product" name="files_root" /> <external-path path="." name="external_storage_root" /> </paths>

更多推荐

如何从统一代码安装Android APK

本文发布于:2023-11-17 02:38:11,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1608501.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:代码   Android   APK

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!