如何使用Unity3D将AndroidJavaObject中的变量转换为C#类

我找不到如何从C#中的AndroidJavaObject获取ListArray变量。
我正在尝试使用CountListArray中存储为AndroidJavaObject的项目数创建for函数。 但我需要知道如何从AndroidJavaObject获取Count以及如何正确使用它。
这是我用来获取变量的,也注意到“packages”不是AndroidJavaObject[]

 AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject currentActivity = jc.GetStatic("currentActivity"); int flag = new AndroidJavaClass("android.content.pm.PackageManager").GetStatic("GET_META_DATA"); AndroidJavaObject pm = currentActivity.Call("getPackageManager"); AndroidJavaObject packages = pm.Call("getInstalledApplications", flag); 

在这一点上它是非常基本的,但它的工作得益于这个如何使用Unity3D安装应用程序列表的一些帮助?

到目前为止的进展停止了获取图标,其他一切工作完美,我需要一种方法来获得一个链接到图标的string ,或者图标的Texture2D
另一种选择是使用包含drawableAndroidJavaObject ,就好像它是Texture2D一样。 我不知道怎么做到这一点。
我的另一个想法是将它转换为另一个变量,比如可以传输和转换回来的byte[] ,但是我还没有找到一种在这种情况下工作的方法。

 int count = packages.Call("size"); AndroidJavaObject[] links = new AndroidJavaObject[count]; string[] names = new string[count]; Texture2D[] icons = new Texture2D[count]; int ii =0; for(int i=0; ii<count;){ //get the object AndroidJavaObject currentObject = packages.Call("get", ii ); try{ //try to add the variables to the next entry links[i] = pm.Call("getLaunchIntentForPackage", currentObject.Get("processName")); names[i] = pm.Call("getApplicationLabel", currentObject); icons[i] = pm.Call("getApplicationIcon", currentObject); Debug.Log ("(" + ii + ") " + i +" "+ names[i]); //go to the next app and entry i++; ii++; } catch { //if it fails, just go to the next app and try to add to that same entry. Debug.Log("skipped "+ ii); ii++; } } 

我真的不想在这里连续问两个问题,我为必须这样做而道歉,但这是一个困难且看似尴尬的情况,几乎没有文件(我能找到)。

首先,关于Unity3D和Android之间互操作的文档充其量只是稀缺。

最重要的是Unity公开使用java对象的唯一接口是AndroidJavaObject并且该接口只定义了几个方法。 你只能使用那些而只能使用那些。

这意味着在使用java数组时,您不会获得Count对象,并且您仍将使用AndroidJavaObject

 int count = packages.Call("size"); //getting the size of the array for( int i = 0; i < count; i++ ) { //getting the object at location i AndroidJavaObject currentObject = packages.Call("get", i ); //use currentObject using the same methods as before: Call, CallStatic, Get, GetStatic } 

我知道这很冗长,编写这样的代码很难测试,你需要制作和apk并将其部署到设备来检查它是否运行。

可能更快的方法是创建自己的java类,在java端执行所有这些操作,并公开一个从Unity端调用的方法。 这样至少可以在制作一个你将在Plugins/Android文件夹中添加的jar时获得静态类型的好处。

我试图在这里做同样的事情,但我的发射器必须只显示CardBoard应用程序。 我决定在java中创建一个库并将其作为插件导入Unity:

这是我的Java类:

 public class Launcher extends UnityPlayerActivity { private List cbApps; @Override protected void onStart() { super.onStart(); PackageManager pm= getPackageManager(); List lista = pm.getInstalledApplications(PackageManager.GET_META_DATA); cbApps= new LinkedList(); for(ApplicationInfo ai : lista){ Intent intentToResolve = new Intent(Intent.ACTION_MAIN); intentToResolve.addCategory("com.google.intent.category.CARDBOARD"); intentToResolve.setPackage(ai.packageName); if(pm.resolveActivity(intentToResolve, 0)!=null) { cbApps.add(ai); } } } public int getListSize(){ return cbApps.size(); } 

这是我的C#方法:

 void Start () { AndroidJavaClass unity = new AndroidJavaClass ("com.unity3d.player.UnityPlayer"); AndroidJavaObject currentActivity = unity.GetStatic ("currentActivity"); texto.text=""+currentActivity.Call ("getListSize"); } 

这样我就可以用Java创建访问列表所需的每个方法。 我仍然遇到的问题是试图获取图标的Texture2D。 我已经尝试从Java中返回Drawable并使用Call进行访问,但它根本不起作用。 我已经工作了2天,如果找到解决方案,我会告诉你的。

编辑:最后我可以得到图像:

首先在Java中我创建了这个方法:

 public byte[] getIcon(int i) { BitmapDrawable icon= (BitmapDrawable)context.getPackageManager().getApplicationIcon(cbApps.get(i)); Bitmap bmp = icon.getBitmap(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); return byteArray; } 

这样我可以访问表示Unity中Drawable的Byte数组,并将其显示为Plane的主要纹理:

 void Start () { using (AndroidJavaClass unity = new AndroidJavaClass ("com.unity3d.player.UnityPlayer")) { context = unity.GetStatic ("currentActivity"); } using (AndroidJavaClass pluginClass=new AndroidJavaClass("com.droiders.launcher.Launcher")) { launcher= pluginClass.CallStatic("getInstance", context); byte[] bytes= launcher.Call("getIcon",0); Texture2D tex= new Texture2D(2,2); tex.LoadImage(bytes); plane.GetComponent().material.mainTexture=tex; } } 

希望它能帮到你。 这很难,但这只野兽已被驯服:P也感谢大家的想法。