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

时间:2015-07-05 22:05:25

标签: java c# android arraylist unity3d

我无法找到如何从C#中的ListArray获取AndroidJavaObject变量 我正在尝试使用forCount创建ListArrayAndroidJavaObject中存储为Count的项目数。但我需要知道如何从AndroidJavaObject获取AndroidJavaObject[]以及如何正确使用它 这是我用来获取变量的,也注意到“包”不是AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject currentActivity = jc.GetStatic<AndroidJavaObject>("currentActivity"); int flag = new AndroidJavaClass("android.content.pm.PackageManager").GetStatic<int>("GET_META_DATA"); AndroidJavaObject pm = currentActivity.Call<AndroidJavaObject>("getPackageManager"); AndroidJavaObject packages = pm.Call<AndroidJavaObject>("getInstalledApplications", flag);

string

在这一点上非常简陋,但它的工作得益于How to get installed apps list with Unity3D?

的一些帮助

到目前为止的进展停止获取图标,其他一切都很完美,我需要一种方法来获得以某种方式链接到图标的Texture2D,或{{1另一个替代方案是使用包含AndroidJavaObject的{​​{1}},就好像它是Texture2D一样。我不知道如何完成任何这个。
我的另一个想法是将它转换为另一个变量,如drawable,可以转移和转换回来,但我还没有找到一个方法在这种情况下有效的。

byte[]

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

2 个答案:

答案 0 :(得分:3)

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

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

这意味着在使用java数组时你没有得到Count对象,而你仍然会使用AndroidJavaObject

int count = packages.Call<int>("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时获得静态类型的好处。

答案 1 :(得分:2)

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

这是我的Java类:

public class Launcher extends UnityPlayerActivity {

private List<ApplicationInfo> cbApps;

@Override
protected void onStart() {
    super.onStart();

    PackageManager pm= getPackageManager();
    List<ApplicationInfo> lista = pm.getInstalledApplications(PackageManager.GET_META_DATA);
    cbApps= new LinkedList<ApplicationInfo>();

    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<AndroidJavaObject> ("currentActivity");
    texto.text=""+currentActivity.Call<int> ("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<AndroidJavaObject> ("currentActivity");
    }
    using (AndroidJavaClass pluginClass=new AndroidJavaClass("com.droiders.launcher.Launcher")) {
        launcher= pluginClass.CallStatic<AndroidJavaObject>("getInstance", context);
        byte[] bytes= launcher.Call<byte[]>("getIcon",0);
        Texture2D tex= new Texture2D(2,2);
        tex.LoadImage(bytes);
        plane.GetComponent<Renderer>().material.mainTexture=tex;
    }

}

希望它对你有所帮助。它已经很难但这只野兽已被驯服:P 也感谢大家的想法。