Introduction
Let me share a sample code in C# which communicates with android java classes.
What I will do is open an AlertDialog from unity c# scripts.
In the process I will show you how to access android classes, derive from an android java class, override its methods, also how to execute task in android main thread.
You can use the technique used in the document to access anything that is accessible in android.
If you want to say create a custom dialog you can create a jar library which has the required code and access the classes in the jar by using the same technique.
The jar library and the resources of course should be kept in the Assets/Plugins/Android folder.
Accessing the activity class
In unity AndroidJavaClass represents the java.lang.Class and AndroidJavaObject the java.lang.Object. We will use both of these classes to get the instance of Activity class.
// Obtain activity AndroidJavaClass unityPlayer = new AndroidJavaClass ("com.unity3d.player.UnityPlayer"); AndroidJavaObject activity = unityPlayer.GetStatic< AndroidJavaObject > ("currentActivity");
Running code on UI thread
We will use the method runOnUiThread of the activity to run on UI thread. Here we will use AndroidJavaRunnable class which represents java.lang.Runnable.
// Here we are using lambda expression you can also pass a function as argument to the AndroidJavaRunnable class activity.Call("runOnUiThread", new AndroidJavaRunnable(() => { // put your code there }
Deriving from a Java interface
AndroidJavaProxy will be used to derive from a java interface. To derive from a java interface first derive from AndroidJavaProxy and then call the java interface from the constructor as show below,
private class PositiveButtonListner : AndroidJavaProxy { public PositiveButtonListner() : base("android.content.DialogInterface$OnClickListener") { } public void onClick(AndroidJavaObject obj, int value ) { // do your stuff here, it will be overridden from DialogInterface.OnClickListener } }
Complete source code
using UnityEngine; using System.Collections; public class AndroidDialog : MonoBehaviour { const int ButtonWidth = 256; const int ButtonHeight = 64; private string mMessage = "See My Android Dialog"; private bool mYesPressed = false; private bool mNoPressed = false; // Use this for initialization void Start () { } // Update is called once per frame void Update () { } void OnGUI() { if (GUI.Button(new Rect((Screen.width-ButtonWidth)/2, (Screen.height-ButtonHeight)/2, ButtonWidth, ButtonHeight), "ShowDialog")) { showDialog(); } if (mYesPressed) { GUI.Label(new Rect((Screen.width-ButtonWidth)/2, (Screen.height-ButtonHeight)/2 + 2 * ButtonHeight, ButtonWidth, ButtonHeight), "You Pressed Yes"); } if (mNoPressed) { GUI.Label(new Rect((Screen.width-ButtonWidth)/2, (Screen.height-ButtonHeight)/2 + 2 * ButtonHeight, ButtonWidth, ButtonHeight), "You Pressed No"); } } // Lets put our android specific code under the macro UNITY_ANDROID #if UNITY_ANDROID // Lets create some listners. // These listners will be passed to android // Create the postive action listner class // It has to be derived from the AndroidJavaProxy class // Make the methods as same as that of DialogInterface.OnClickListener private class PositiveButtonListner : AndroidJavaProxy { private AndroidDialog mDialog; public PositiveButtonListner(AndroidDialog d) : base("android.content.DialogInterface$OnClickListener") { mDialog = d; } public void onClick(AndroidJavaObject obj, int value ) { mDialog.mYesPressed = true; mDialog.mNoPressed = false; } } // Create the postive action listner class // It has to be derived from the AndroidJavaProxy class // Make the methods as same as that of DialogInterface.OnClickListener private class NegativeButtonListner : AndroidJavaProxy { private AndroidDialog mDialog; public NegativeButtonListner(AndroidDialog d) : base("android.content.DialogInterface$OnClickListener") { mDialog = d; } public void onClick(AndroidJavaObject obj, int value ) { mDialog.mYesPressed = false; mDialog.mNoPressed = true; } } #endif private void showDialog() { #if UNITY_ANDROID // Obtain activity AndroidJavaClass unityPlayer = new AndroidJavaClass ("com.unity3d.player.UnityPlayer"); AndroidJavaObject activity = unityPlayer.GetStatic< AndroidJavaObject> ("currentActivity"); // Lets execute the code in the UI thread activity.Call("runOnUiThread", new AndroidJavaRunnable(() => { // Create an AlertDialog.Builder object AndroidJavaObject alertDialogBuilder = new AndroidJavaObject("android/app/AlertDialog$Builder", activity); // Call setMessage on the builder alertDialogBuilder.Call< AndroidJavaObject> ("setMessage", mMessage); // Call setCancelable on the builder alertDialogBuilder.Call< AndroidJavaObject> ("setCancelable", true); // Call setPositiveButton and set the message along with the listner // Listner is a proxy class alertDialogBuilder.Call< AndroidJavaObject> ("setPositiveButton", "Yes", new PositiveButtonListner(this)); // Call setPositiveButton and set the message along with the listner // Listner is a proxy class alertDialogBuilder.Call< AndroidJavaObject> ("setNegativeButton", "No", new NegativeButtonListner(this)); // Finally get the dialog instance and show it AndroidJavaObject dialog = alertDialogBuilder.Call< AndroidJavaObject> ("create"); dialog.Call("show"); })); #endif } }
Hi There,
ReplyDeleteZoooooooom! That’s how speedy and easy this read was! Looking forward to more of such powerful content on Accessing android java classes from Unity 3D!
I have a 1.7 year of exp in C. I wanted to develop a project from job point of view which can make a resume much stronger.
If a program is large, it is subdivided into a number of smaller programs that are called modules or subprograms. If a complex problem is solved using more modules, this approach is known as modular programming.
Very useful article, if I run into challenges along the way, I will share them here.
Obrigado,
Kevin