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_T
You can build a jar/aar plugin and call it from C#. That's more easier to do.
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.
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 line of code.
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 header = new Dictionary();
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 = "Stat: " + www.progress;
yield return null;
}
byte[] yourBytes = www.bytes;
GameObject.Find("TextDebug").GetComponent().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 = "Created Dir";
}
try
{
//Now Save it
System.IO.File.WriteAllBytes(savePath, yourBytes);
Debug.Log("Saved Data to: " + savePath.Replace("/", "\\"));
GameObject.Find("TextDebug").GetComponent().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 = "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("ACTION_VIEW");
int FLAG_ACTIVITY_NEW_TASK = intentObj.GetStatic("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("fromFile", fileObj);
intent.Call("setDataAndType", uri, "application/vnd.android.package-archive");
intent.Call("addFlags", FLAG_ACTIVITY_NEW_TASK);
intent.Call("setClassName", "com.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity");
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayer.GetStatic("currentActivity");
currentActivity.Call("startActivity", intent);
GameObject.Find("TextDebug").GetComponent().text = "Success";
return true;
}
catch (System.Exception e)
{
GameObject.Find("TextDebug").GetComponent().text = "Error: " + e.Message;
return false;
}
}
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 = "Installing App";
try
{
//Get Activity then Context
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayer.GetStatic("currentActivity");
AndroidJavaObject unityContext = currentActivity.Call("getApplicationContext");
//Get the package Name
string packageName = unityContext.Call("getPackageName");
string authority = packageName + ".fileprovider";
AndroidJavaClass intentObj = new AndroidJavaClass("android.content.Intent");
string ACTION_VIEW = intentObj.GetStatic("ACTION_VIEW");
AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent", ACTION_VIEW);
int FLAG_ACTIVITY_NEW_TASK = intentObj.GetStatic("FLAG_ACTIVITY_NEW_TASK");
int FLAG_GRANT_READ_URI_PERMISSION = intentObj.GetStatic("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("getUriForFile", unityContext, authority, fileObj);
intent.Call("setDataAndType", uri, "application/vnd.android.package-archive");
intent.Call("addFlags", FLAG_ACTIVITY_NEW_TASK);
intent.Call("addFlags", FLAG_GRANT_READ_URI_PERMISSION);
currentActivity.Call("startActivity", intent);
GameObject.Find("TextDebug").GetComponent().text = "Success";
}
catch (System.Exception e)
{
GameObject.Find("TextDebug").GetComponent().text = "Error: " + e.Message;
success = false;
}
return success;
}
EDIT:
If you get the Exception:
Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.packageItemInfo.loadXmlMetaData(android.content.pm.PackageManager.java.lang.String)'
You have to do few things.
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.Create a file called "AndroidManifest.xml" in your UnityProject/Assets/Plugins/Android directory and put the code below into it.
Make sure to replace "com.company.product" with your own package name. There are 2 instances where this appeared. You must replace both of them:
These are found in package="com.company.product" and android:authorities="com.company.product.fileprovider". Don't change or remove the "fileprovider" and don't change anything else.
Here is the "AndroidManifest.xml" file:
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.
Make sure to replace "com.company.product" with your own package name. It only appeared once.
Here is what you should put into this "provider_paths.xml" file: