6

I want to get Android version information from Unity. I know that SystemInfo.operatingSystem can be used to do this but it does not have all the information such as release number, code-name and other info.

I decided to make a tiny plugin with Unity's AndroidJavaClass class using Android's Build.VERSION class but ran into a problem I can't explain.

When I do:

AndroidJavaClass("android.os.Build.VERSION");

I get class not found exception.

It works when use:

AndroidJavaClass("android.os.Build$VERSION");

Notice that I replaced "." with "$" and the class can now be found.

I have written many plugins in the past and have never ran into this problem before. For example, when I accessed the Android's Uri class, I used AndroidJavaClass("android.net.Uri"); and it worked. I didn't have to put "$" before "Uri".

What makes accessing android.net.Uri different from accessing android.os.Build.VERSION?

Why do you have to put "$" between Build and VERSION in order for AndroidJavaClass to find this class?

By the way, here is the working plugin of Build.VERSION in Unity:

public class AndroidVersion
{
    static AndroidJavaClass versionInfo;

    static AndroidVersion()
    {
        versionInfo = new AndroidJavaClass("android.os.Build$VERSION");
    }

    public static string BASE_OS
    {
        get
        {
            return versionInfo.GetStatic<string>("BASE_OS");
        }
    }

    public static string CODENAME
    {
        get
        {
            return versionInfo.GetStatic<string>("CODENAME");
        }
    }

    public static string INCREMENTAL
    {
        get
        {
            return versionInfo.GetStatic<string>("INCREMENTAL");
        }
    }

    public static int PREVIEW_SDK_INT
    {
        get
        {
            return versionInfo.GetStatic<int>("PREVIEW_SDK_INT");
        }
    }

    public static string RELEASE
    {
        get
        {
            return versionInfo.GetStatic<string>("RELEASE");
        }
    }

    public static string SDK
    {
        get
        {
            return versionInfo.GetStatic<string>("SDK");
        }
    }

    public static int SDK_INT
    {
        get
        {
            return versionInfo.GetStatic<int>("SDK_INT");
        }
    }

    public static string SECURITY_PATCH
    {
        get
        {
            return versionInfo.GetStatic<string>("SECURITY_PATCH");
        }
    }

    public static string ALL_VERSION
    {
        get
        {
            string version = "BASE_OS: " + BASE_OS + "\n";
            version += "CODENAME: " + CODENAME + "\n";
            version += "INCREMENTAL: " + INCREMENTAL + "\n";
            version += "PREVIEW_SDK_INT: " + PREVIEW_SDK_INT + "\n";
            version += "RELEASE: " + RELEASE + "\n";
            version += "SDK: " + SDK + "\n";
            version += "SDK_INT: " + SDK_INT + "\n";
            version += "SECURITY_PATCH: " + SECURITY_PATCH;

            return version;
        }
    }
}
Programmer
  • 121,791
  • 22
  • 236
  • 328

1 Answers1

3

android.os.Build$VERSION itself is an inner class and therefore must append $ to let the JRE use the dot sign to determine the packages vs. the inner class.

Having it android.os.Build.VERSION will mean go to a class called VERSION inside Build package, whereas android.os.Build$VERSION will mean go to an inner class Version within the Build class inside os package

Rod_Algonquin
  • 26,074
  • 6
  • 52
  • 63
  • Ok, that makes sense. Does that mean that [`android.net.Uri`](https://developer.android.com/reference/android/net/Uri.html) is **NOT** an inner class? Since I will be making more plugins in the feature, how do I know if a class is an inner class from the Android documentation? – Programmer Jul 16 '17 at 04:34
  • Yes, Uri is a completely a separate class, to know an inner class is to either go dig to the source code or just check the name of the class itself. (parent_name).(innner_class_name) – Rod_Algonquin Jul 16 '17 at 04:37
  • Got it. Thanks for the info. – Programmer Jul 16 '17 at 04:44