- Home /
How can I access Native Android Classes with parameters?
Hi,
I'm building an Android application in Unity 3D and I need to use a jar file. I need to call a special method inside that jar file and the main calss extends Activity :
public static void extendWindow(Window w, boolean extend)
Now, I can call any java methods inside android with :
AndroidJavaClass pluginClass = new AndroidJavaClass("com.myplugin.My_Plugin");
GetComponent<Text>().text = pluginClass.CallStatic<string>("getMessage");
But how can I create that Window w object inside Android activity and send it as a parameter to Android Java?
pluginClass.CallStatic("extendWindow","Window w", true);
This is not working, any suggestions?
Answer by liortal · Aug 12, 2016 at 05:42 PM
You have 2 different options to achieve this. Both options use the AndroidJavaObject and AndroidJavaClass classes:
Create another method (in Java) that will simplify things, for example, by creating the Window object in Java. This means you shouldn't have to worry about creating native Android types in your Unity code (their creation might be a bit long and error prone when done from Unity). In your Unity code you'd call the "simpler" method which will in turn create a Window and pass that to the method in the .jar library that you want to use.
Create a Window object from Unity and pass that as a parameter to the method in your .jar library.
Let's go with option #2. A bit about AndroidJavaObject - this is a helper class that allows interacting with Java classes in Android. When you construct an object instance, you're effectively calling the class's Java constructor with the passed arguments.
In your example, what you're trying to do is create an instance of the android.view.Window class. Looking at the documentation, there's only 1 constructor that looks like this: Window (Context context)
So, the Unity you should be using may look something like this: // Create a reference to the plugin class AndroidJavaClass pluginClass = new AndroidJavaClass("com.myplugin.My_Plugin");
// Get Unity's main activity (Context)
var actClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
var context = actClass.GetStatic<AndroidJavaObject>("currentActivity");
// Create an android.view.Window instance (should pass a Context as a parameter)
AndroidJavaObject window = new AndroidJavaObject("android.view.Window", context);
pluginClass.CallStatic<string>("extendWindow", window);
A couple of things to note:
I haven't tested this code, but it should work.
AndroidJavaObjects implement a Dispose method to dispose of native JNI resources. all calls for creating such objects must be wrapped in proper using (...) clauses in production code to avoid any issues.
I tried this approach with wrong parameters.
When I tried your sample code I get following error :
java.lang.InstantiationException: Cant' instantiate class android.vire.Window abstract class or interface ...
I think this line is responsible :
AndroidJavaObject window = new AndroidJavaObject("android.view.Window", context);
I think Unity can't create a java class instance without a static constructor.
Sorry, the Window class is abstract.. you cannot create it.. What exactly are you trying to do? which window should get passed to that method ?
You could get the Window associated with your activity like this:
AndroidJavaObject window = actClass.Call("getWindow");
Then use this as I posted before.
I'm working on an smart glass called OGD R7. I'm trying to switch it to 3D stereo mode. In order to do that firm provided me a jar file and send me some Android sample codes. I decompiled their JAR file and access the method below :
public static void extendWindow(Window w, boolean extend)
{
if (w != null)
{
if (extend) {
w.setFlags(Integer.$$anonymous$$IN_VALUE, Integer.$$anonymous$$IN_VALUE);
} else {
w.clearFlags(Integer.$$anonymous$$IN_VALUE);
}
sWindowSurfaceExtended = extend;
}
else
{
throw new IllegalArgumentException("Window is not valid");
}
}
And this is how they call it inside Android Studio :
public void buttonExtendWindow(View v) {
extended = !extended;
ExtendDisplay.extendWindow(getWindow(), extended);
Display$$anonymous$$etrics metrics = new Display$$anonymous$$etrics();
ExtendDisplay.getDisplay$$anonymous$$etrics(this, getWindow(), metrics);
Log.d(TAG, "window width : " + metrics.widthPixels);
Log.d(TAG, "window height : " + metrics.heightPixels);
}
As you can see, I need to call extendWindow method with getWindow as parameter. I'll try the code you wrote above and post the result.
Since actClass needs to return a type I changed your code to :
AndroidJavaObject window = actClass.Call<AndroidJavaObject>("getWindow");
And
AndroidJavaObject window = actClass.CallStatic<AndroidJavaObject>("getWindow");
Unfortunately no of them worked, Unity keep telling me there is no static method called getWindow.
There is no static method called getWindow:
This is how you should call it: AndroidJavaObject window = actClass.Call("getWindow");
If I call it like that, error CS0029: Cannot implicitly convert type void' to
UnityEngine.AndroidJavaObject'
pops up. This is for voids I guess...
I think this text editor replaces what i type.
AndroidJavaObject window = actClass.Call<AndroidJavaObject>("getWindow");
this is the correct way
Same error again , no static method called getWindow. $$anonymous$$aybe accessing the native Activity solves this error. I'll try.
Your answer
Follow this Question
Related Questions
Android Unity, Screen Recording and MediaProjection APIs - UnityPlayerActivity hang. 0 Answers
How to start the UnityPlayerActivity from a java plugin that overrides the basic Android Activity 1 Answer
(Android) mUnityPlayers SurfaceView Access 2 Answers
Android plugin & Activity help needed - "GetMethodID method not found" problems 0 Answers