Maz*_*har 2 c# android unity-game-engine android-intent
我找到了Java代码片段.如何在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);
Run Code Online (Sandbox Code Playgroud)
你可以构建一个jar/aar插件并从C#中调用它.这样做更容易.
另一种解决方案是在 没有插件的情况下直接使用AndroidJavaObject和AndroidJavaClass执行此操作.这样做AndroidJavaObject并AndroidJavaClass需要大量测试才能做到正确.以下是我用来做的事情.它下载APK然后安装它.
首先创建一个名为"TextDebug"的UI文本,这样您就可以看到下载/安装过程中发生了什么.如果您不这样做,您必须注释掉或删除所有GameObject.Find("TextDebug").GetComponent<Text>().text...代码行.
void Start()
{
StartCoroutine(downLoadFromServer());
}
IEnumerator downLoadFromServer()
{
string url = "http://apkdl.androidapp.baidu.com/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.net.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;
}
}
Run Code Online (Sandbox Code Playgroud)
对于Android API 24及更高版本,由于API已更改,因此需要使用不同的代码.下面的C#代码基于这个 Java答案.
//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;
}
Run Code Online (Sandbox Code Playgroud)
编辑:
如果你得到例外:
尝试调用虚拟方法'android.content.res.XmlResourceParser android.content.pm.packageItemInfo.loadXmlMetaData(android.c ontent.pm.PackageMan ager.java.lang.Strin g)'
你必须做一些事情.
1.将"android-support-v4.jar"从"AndroidSDK/extras/android/support/v4/android-support-v4.jar" 目录复制到"UnityProject/Assets/Plugins/Android"目录.
2.在UnityProject/Assets/Plugins/Android目录中创建一个名为"AndroidManifest.xml"的文件,并将下面的代码放入其中.
确保将"com.company.product"替换为您自己的包名称.这有两个出现的情况.您必须更换它们:
这些可以在package ="com.company.product"和android:authorities ="com.company.product.fileprovider"中找到.不要更改或删除"fileprovider",也不要更改其他任何内容.
这是"AndroidManifest.xml"文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.product" xmlns:tools="http://schemas.android.com/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="com.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>
Run Code Online (Sandbox Code Playgroud)
3.在"UnityProject/Assets/Plugins/Android/res/xml"目录中创建一个名为" provider_paths.xml " 的新文件,并将下面的代码放入其中.如您所见,您必须创建一个res,然后创建一个xml文件夹.
确保将"com.company.product"替换为您自己的包名称.它只出现过一次.
以下是您应该在此" provider_paths.xml "文件中添加的内容:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--<external-path name="external_files" path="."/>-->
<external-path path="Android/data/com.company.product" name="files_root" />
<external-path path="." name="external_storage_root" />
</paths>
Run Code Online (Sandbox Code Playgroud)
我只是想对@Programmer 给出的精彩答案添加更新,以反映对 Android SDK 和 Unity 的更改。我希望它对其他人有用。我正在使用 SDK 版本 26 和 Unity 2017.3.1。我对几乎所有这些都是新手,所以如果我错过或误解了任何东西,请纠正我!
您需要将 android.permission.REQUEST_INSTALL_PACKAGES 添加到您的 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.productsomethingelse" xmlns:tools="http://schemas.android.com/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="com.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-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-sdk android:minSdkVersion="24" android:targetSdkVersion="26" />
</manifest>
Run Code Online (Sandbox Code Playgroud)
请注意,我还将com.company.product的第一个实例更改为com.company.productsomethingelse
现在应该可以正常构建并工作了,尽管在构建过程中 Unity 发出警告OBSOLETE - 不推荐在 Assets/Plugins/Android/res 中提供 Android 资源,请将您的资源移至 AAR 或 Android 库。. 要解决这个问题,请创建一个新的 zip 文件并将您的 AndroidManifest.xml 放在 zip 的顶层。然后将@Programmer 详述的 provider_paths.xml 添加到文件夹结构res/xml/provider_paths.xml 中的 zip 中 。将 zip 重命名为 .aar 文件扩展名,然后将其拖到您的 Unity 项目 Assets/Plugins 文件夹中。我将 AndroidManifest.xml 条目更改为com.company.productsomethingelse的原因是当我使用com.company.productUnity 构建过程引发了命名冲突。我认为因为清单现在在一个单独的 aar 中,所以它需要有一个不同的包名。
| 归档时间: |
|
| 查看次数: |
6645 次 |
| 最近记录: |