化石原创文章,转载请注明来源并保留原文链接


API Level是不同的Android version对应的一个唯一的数字,用来标识该Android version提供的框架(framework)API。

Platform VersionAPI LevelVERSION_CODEOther
Android 6.023MARSHMALLOW
Android 5.122LOLLIPOP_MR1
Android 5.021LOLLIPOP
Android 4.4W20KITKAT_WATCHKitKat for Wearables Only
Android 4.419KITKAT
Android 4.318JELLY_BEAN_MR2
Android 4.2, 4.2.217JELLY_BEAN_MR1
Android 4.1, 4.1.116JELLY_BEAN
Android 4.0.3, 4.0.415ICE_CREAM_SANDWICH_MR1
Android 4.0, 4.0.1, 4.0.214ICE_CREAM_SANDWICH
Android 3.213HONEYCOMB_MR2
Android 3.1.x12HONEYCOMB_MR1
Android 3.0.x11HONEYCOMB
Android 2.3.4
Android 2.3.3
10GINGERBREAD_MR1
Android 2.3.2

Android 2.3.1

Android 2.3
9GINGERBREAD
Android 2.2.x8FROYO
Android 2.1.x7ECLAIR_MR1
Android 2.0.16ECLAIR_0_1
Android 2.05ECLAIR
Android 1.64DONUT
Android 1.53CUPCAKE
Android 1.12BASE_1_1
Android 1.01BASE

化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


	string path;

	void Start () {
		path = "/storage/emulated/0/Android/data/test.apk";
		Debug.Log (path);

		GameObject.Find ("Canvas/Button").GetComponent<Button> ().onClick.AddListener (OnClick);
	}
	
	// Update is called once per frame
	void OnClick () {
		installApp (path);
	}

	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;
		}
	}

方法installApp能通过android安装指定路径下的apk。跑起来后,如果apk存在,会弹出对话框,让用户确认安装;安装完毕,会弹出对话框让用户选择“完成”还是“打开”。

API 24以上:

//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;
}

化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


	private static void CloneDirectory(string root, string dest)
	{
		foreach (var directory in Directory.GetDirectories(root))
		{
			string dirName = Path.GetFileName(directory);
			if (!Directory.Exists(Path.Combine(dest, dirName)))
			{
				Directory.CreateDirectory(Path.Combine(dest, dirName));
			}
			CloneDirectory(directory, Path.Combine(dest, dirName));
		}

		foreach (var file in Directory.GetFiles(root))
		{
			File.Copy(file, Path.Combine(dest, Path.GetFileName(file)));
		}
	}

化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


玩Cesium,经常会遇到加载gltf文件。这个文件格式3DS MAX本身不是内置的,但是可以通过插件来完成。

Babylon有该插件。文档地址:

https://doc.babylonjs.com/resources/3dsmax_to_gltf

通过文档,我们可以得到插件的下载地址:

https://github.com/BabylonJS/Exporters/releases

找到页面上的Assets,展开后就可以看到为不同的max 版本准备好的插件版本。比如Max_2015.zip。还有Installer.zip。

不想自己手动装,就直接下载Installer.zip安装。这里我只说手动的方式。

举例,为max 2019安装插件:

1、下载Max_2019.zip

2、解压

3、拷贝解压后的全部dll文件

4、复制到3ds max 2019安装目录下的bin/assemblies目录下,不要新建什么目录,直接拷贝所有的dll到该目录下。

5、打开3ds max 2019,等准备好一会,就会在原来的Help菜单后面看到Babylon菜单。就是我们的导出glft的菜单。

完成。


化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


在Unity中显示网页,无论是在线的、本地的(需要放置在persistentPath或者streamingAssets中),UniWebView的确是个很好的东西。

测试下来,如果是本地的网页,即使图片数量很大,进入速度也非常快(android,iOS未测)。在显示时候的拖拽也非常顺利。

支持在屏幕指定的矩形范围内绘制(设置intents的top、bottom、left、right)。

图片会原图大小显示,如果超出可显示范围,能左右拖动也只能这样支持。


化石原创文章,转载请注明来源并保留原文链接