4

I'm trying to make an android launcher with Unity3D in C#, Everything is in place except detection of installed apps.

I have tried a lot of different things, but they all get stuck at the same place, accessing getInstalledApplications in the PackageManager.

I think I have managed to replicate the ApplicationInfo class in C#, at least variable storage wise, by studying the android source, so I don't think that's a problem, at least not yet...

Simply put, I need the URI (or something I can use to open the app), the name of the app, and the icon of the app (either a string to its location, or the Texture2D itself), I try for ApplicationInfo because it has all that and then some, but if I have to get them individually or through another method, that's totally fine.

Here is an example of what I am doing now. This happens regardless of whether I use a Class or an Object.

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");

And here's the error I get

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

How do I make this work? Or can you tell/show me another method that will accomplish the goal?

//EDIT Okay I messed with this for HOURS trying every possible combination, and I got it.

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

Now I just gotta figure out how to get the strings and ints i need out of the Java object and into C# strings and ints which is a totally different problem than this....

Jonathan C
  • 117
  • 1
  • 9

1 Answers1

4

You are passing a string as the param for getInstalledApplications instead of an integer.

You need to get your hands on an instance of PackageManager, to do this you'll need to get an Activity, fortunately, Unity can give you that.

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);
Radu Diță
  • 8,910
  • 1
  • 18
  • 27
  • Good point, that fixes a problem I didn't see coming. But it doesn't fix the error I mentioned. – Jonathan C Jul 01 '15 at 08:55
  • That seems to work, however now I get the error `Exception: JNI: unknown signature type 'System.Collections.Generic.List'1[ApplicationInfo]' (obj = System.Collections.Generic.List'1[ApplicationInfo] equal`
    I'm guessing that means I didn't make the Application Info class properly? Or is this a new issue?
    – Jonathan C Jul 01 '15 at 09:26
  • You can't mirror a Java class on the Unity side. You'll always be working with AndroidJavaObject. I've updated my answer to reflect this. – Radu Diță Jul 01 '15 at 10:13
  • Well that fixes that, good to know, and honestly that's a lot easier too. But, a new error has appeared yet again, I'm sorry this must be turning out to be such a bother for you. `AndroidJavaException: Java.lang.NoSuchMethodError: no method with name = 'getInstalledApplications' signature=(I)[Ljava/lang/Object;' in class Landroid/app/ApplicationPackageManager;` – Jonathan C Jul 01 '15 at 11:04
  • Still haven't figured out the answer to this issue. I marked your answer as accepted because I highly doubt I'm getting anyone else's help on this, and you at least gave it a good try. Spent all day on the internet and no one else is trying to do this apparently, so I'm probably just stuck at this. I think the issue is that it's getting the package manager from the app rather than from system. – Jonathan C Jul 02 '15 at 05:51