- Home /
How to Implement Java Interface with AndroidJavaProxy
Hello guys.
I'm building an android game that needs to implement a datepicker, using only unity pro (version 4.5) and c# code. I don't want, or even can use eclipse right now. I'm trying to call the default android datepicker, using AndroidJavaProxy, but I'm not being very successful. According to unity docs (http://docs.unity3d.com/ScriptReference/AndroidJavaProxy.html) , I should be able to achieve that by using this:
using UnityEngine;
using System.Collections;
public class SelectedDate : MonoBehaviour {
public static Date date = System.DateTime.Now;
}
public class DateCallback : MonoBehaviour {
new ("android.app.DatePickerDialog$OnDateSetListener");
void onDateSet(AndroidJavaObject view, int year, int monthOfYear, int dayOfMonth) {
SelectedDate.date = new Date(year, monthOfYear + 1, dayOfMonth);
}
}
public class ExampleClass : MonoBehaviour {
void OnGUI() {
if (GUI.Button(new Rect(10, 10, 450, 100), String.Format("{0:yyyy-MM-dd}", SelectedDate.date))) {
AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
activity.Call("runOnUiThread", AndroidJavaRunnable( new AndroidJavaObject("android.app.DatePickerDialog", activity, new DateCallback(), SelectedDate.date.Year, SelectedDate.date.Month - 1, SelectedDate.date.Day).Call("show");
));
}
}
}
However I keep getting error logs telling me that the script have syntax errors, like Assets/Testepicker.cs(8,13): error CS1519: Unexpected symbol `(' in class, struct, or interface member declaration
The Javascript example on unity docs do work, but would really like to to do this on c# (for further uses, and also learning). Does anyone knows what is the problem with the given script, or know how to properly call android's datepicker (or any other android activity / function)?
Answer by VitorValadares · Nov 18, 2014 at 11:17 AM
Ok, I figured it out. The solution is not as neat as the one provided by unity docs, but at least it works. What I had to do, was to create a new function, so that I could reference it when creating a new Android Java Runnable. Also, I had to store the activity, in order to use it on my Pick Date function.
using UnityEngine;
using System.Collections;
public class SelectedDate {
public static System.DateTime date = System.DateTime.Now;
}
public class DateCallback : AndroidJavaProxy
{
public DateCallback() : base("android.app.DatePickerDialog$OnDateSetListener") { }
public void onDateSet(AndroidJavaObject view, int year, int monthOfYear, int dayOfMonth) {
SelectedDate.date = new System.DateTime(year, monthOfYear + 1, dayOfMonth);
}
}
public class ExampleClass : MonoBehaviour
{
private AndroidJavaObject activity;
void PickDate(){
new AndroidJavaObject("android.app.DatePickerDialog", activity, new DateCallback(), SelectedDate.date.Year, SelectedDate.date.Month - 1, SelectedDate.date.Day).Call("show");
}
void OnGUI()
{
if (GUI.Button(new Rect(10, 10, 450, 100), System.String.Format("{0:yyyy-MM-dd}", SelectedDate.date)))
{
activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
activity.Call("runOnUiThread", new AndroidJavaRunnable(PickDate));
}
}
}
I hope it helps anyone with the same problem. Now I just need to figured it out how to do something like this for iOS...
This is the correct way of doing it. Note that AndroidJavaObject (and AndroidJavaClass that derives it) are both IDisposable. This is because they hold onto JNI references that should not be held for too long (there is a finite number of them you can use). The safe way of doing things is to not hold on to many JNI references, and to release them (by calling Dispose() on the AndroidJavaObject as soon as you're done with it).
I see, but just to be clear, the example given by unity on their website is wrong? At least the way it is there right now.
By the way, thanks for the tips.
Vitor,
Just wanted to say, I've looked everywhere on how to do this. $$anonymous$$ost people solve this problem via plugins, but doing it entirely on the Unity side can have major advantages, and this solution worked perfectly with $$anonymous$$ediaPlayer. A big thank you!
Would love some help on how to use the date once selected from the Android Date Picker Dialogue. On button press (that isn't on GUI) is when the code runs to update the date but the date is selected after the O$$anonymous$$ is pressed so won't update until the selection button is pressed again.
The callback is executed from Java code. This most likely runs on a seperate thread. The easiest solution is to "signal" your code that the date has been changed by setting a boolean to true which is set back to false once you recognised it in Update. In other words something like this:
public class SelectedDate
{
public static System.DateTime date = System.DateTime.Now;
public static bool newDate = false;
}
public class DateCallback : AndroidJavaProxy
{
public DateCallback() : base("android.app.DatePickerDialog$OnDateSetListener") { }
public void onDateSet(AndroidJavaObject view, int year, int monthOfYear, int dayOf$$anonymous$$onth)
{
SelectedDate.date = new System.DateTime(year, monthOfYear + 1, dayOf$$anonymous$$onth);
SelectedDate.newDate = true;
}
}
// inside your $$anonymous$$onoBehaviour
void Update()
{
if(SelectedDate.newDate)
{
SelectedDate.newDate = false;
// do something with "SelectedDate.date"
}
}
@Bunny83 Tested and works perfectly, thank you so much for this. I had a boolean set up but it was running on the $$anonymous$$onobehaviour part of my code, your answer makes a lot more sense.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Android Plugin in Unity - No Return Value 0 Answers
Android Plugin in Unity - No Return Value 0 Answers
How to get connected wifi BSSID ? 1 Answer