如何使用Unity3D获取已安装应用程序列表?

4

我正在尝试使用C#在Unity3D中制作Android启动器,除了检测已安装的应用程序之外,一切都就绪。

我尝试了很多不同的方法,但它们都卡在同一个地方,即访问PackageManager中的getInstalledApplications

我认为我已经成功复制了ApplicationInfo类(至少变量存储方面),通过研究Android源代码,所以我认为这不是问题,至少现在还不是...

简单来说,我需要URI(或其他可以用于打开应用程序的内容)、应用程序的名称和应用程序的图标(可以是指向其位置的字符串或Texture2D本身)。我尝试使用ApplicationInfo,因为它拥有所有这些功能,但如果我必须通过其他方法逐个获取它们,那也完全没问题。

以下是我目前正在进行的工作示例。无论我使用类还是对象,都会发生这种情况。

void Start () {
                AndroidJavaClass pluginClass = new AndroidJavaClass("android.content.pm.PackageManager");

            AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            AndroidJavaObject currentActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");
        Debug.Log(currentActivity.Call<string>("getPackageName"));
        int flag = pluginClass.GetStatic<int>("GET_META_DATA");
        AndroidJavaClass syspackage = currentActivity.Call<AndroidJavaClass>("getPackageManager");

这是我遇到的错误信息

AndroidJavaException: Java.lang.NoSuchMethodError: no method with name = 'getInstalledApplications' signature=Ljava/lang/Class;' in class Lcom.unity3d/player/UnityPlayerActivity;

我该怎么让这个工作?或者你能告诉/展示给我另一种可以达成目标的方法吗?

//编辑 好的,我试了几个小时尝试了每种可能的组合,终于搞定了。

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

现在我只需要想办法从Java对象中获取所需的字符串和整数,并将其转换为C#字符串和整数,这是一个完全不同的问题....

1个回答

4

你正在将字符串作为 getInstalledApplications 的参数传递,而不是整数。

你需要获取 PackageManager 的实例,为此你需要获取一个 Activity,幸运的是,Unity 可以提供给你。

AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");

AndroidJavaObject packageManager = currentActivity.Call<AndroidJavaObject>("getPackageManager");

int flag = pluginClass.GetStatic<int>("GET_META_DATA");

AndroidJavaObject[] arrayOfAppInfo = packageManager.Call<AndroidJavaObject[]>("getInstalledApplications", flag);

好的,这解决了一个我没有预料到的问题。 但它并没有修复我提到的错误。 - Jonathan C
似乎这个问题已经解决了,但是现在我收到了错误信息 Exception: JNI: unknown signature type 'System.Collections.Generic.List'1[ApplicationInfo]' (obj = System.Collections.Generic.List'1[ApplicationInfo] equal。我猜这意味着我没有正确地创建 Application Info 类?还是这是一个新的问题? - Jonathan C
你不能在Unity端将Java类映射为镜像。你总是要使用AndroidJavaObject。我已经更新了我的答案以反映这一点。 - Radu Diță
那样做就解决了,好了解啊,而且说实话这样也更容易。但是,又出现了一个新的错误,很抱歉这一定会给您带来麻烦。"AndroidJavaException: Java.lang.NoSuchMethodError: no method with name = 'getInstalledApplications' signature=(I)[Ljava/lang/Object;' in class Landroid/app/ApplicationPackageManager; "。 - Jonathan C
我还没有找到解决这个问题的答案。我标记了你的答案为已接受,因为我非常怀疑其他人会帮助我解决这个问题,而你至少尝试了一下。我整天在网上搜索,显然没有其他人在尝试解决这个问题,所以我可能就卡在这里了。我认为问题在于它从应用程序获取软件包管理器而不是从系统获取。 - Jonathan C
你的对象上的该方法是否已明确地被标记为可在Unity中使用? - Oke Uwechue

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接