- Home /
Compass java plugin for Unity Android
Hello,
I'm trying to create a java plugin to get compass info from Android. I started with this example:
http://docwiki.unity3d.com/uploads/Main/AndroidJavaPluginProject.zip
Then, I tried to include the necessary code from:
The problem I found is that it is necessary to create a SensorListener and I'm not sure if this will work as a Unity plugin.
Anyone has tried to do this?
This is my piece of code:
private final SensorListener mSensorListener = new SensorListener() { public void onSensorChanged(int sensor, float[] values) { if (sensor == SensorManager.SENSOR_MAGNETIC_FIELD) { float xmag = values[0]; float ymag = values[1]; float zmag = values[2]; } }
public void onAccuracyChanged(int sensor, int accuracy)
{
int i=0;
}
};
The alternative is to code the plugin with native code (NDK), but sensor data is only available with Android SDK 2.3 (Almost every android phone runs 2.2 nowadays)
Thanks in advance,
Joel
Answer by pfranza · Jan 20, 2011 at 09:06 PM
I think you should be able to do it. However you will have to pull the data from the sensor each cycle, instead of having the data pushed to you from the java EventBus.
The following is just pseudo-code so don't hold me to it but it should be something like:
public class SensorClass {
private Activity mActivity;
float xmag; float ymag; float zmag;
private final SensorListener mSensorListener = new SensorListener() {
public void onSensorChanged(int sensor, float[] values) {
if (sensor == SensorManager.SENSOR_MAGNETIC_FIELD) {
xmag = values[0];
ymag = values[1];
zmag = values[2];
}
}
public void onAccuracyChanged(int sensor, int accuracy) {
int i=0;
}
};
public SensorClass(Activity currentActivity) { mActivity = currentActivity;
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
mSensorManager.registerListener(mSensorListener, mSensor,
SensorManager.SENSOR_DELAY_GAME);
}
public float getX() { return xmag; }
public float getY() { return ymag; }
public float getZ() { return zmag; }
}
This way you have a standalone java class that is aggregating the sensor updates for you then you just need to instantiate and call the getters from your .cs code
public class CallJavaCode : MonoBehaviour {
private IntPtr JavaClass; private float xValue; private float yValue; private float zValue;
void Start () {
JavaVM.AttachCurrentThread();
IntPtr cls_Activity = JNI.FindClass("com/unity3d/player/UnityPlayer");
int fid_Activity = JNI.GetStaticFieldID(cls_Activity, "currentActivity", "Landroid/app/Activity;");
IntPtr obj_Activity = JNI.GetStaticObjectField(cls_Activity, fid_Activity);
Debug.Log("obj_Activity = " + obj_Activity);
IntPtr cls_JavaClass = JNI.FindClass("org/example/SensorClass");
int mid_JavaClass = JNI.GetMethodID(cls_JavaClass, "<init>", "(Landroid/app/Activity;)V");
IntPtr obj_JavaClass = JNI.NewObject(cls_JavaClass, mid_JavaClass, obj_Activity);
JavaClass = JNI.NewGlobalRef(obj_JavaClass);
// this is where the JNI magic happens
xValue = JNI.CallFloatMethod(JavaClass, JNI.GetMethodID(cls_JavaClass, "getX", "()F"))
yValue = JNI.CallFloatMethod(JavaClass, JNI.GetMethodID(cls_JavaClass, "getY", "()F"))
zValue = JNI.CallFloatMethod(JavaClass, JNI.GetMethodID(cls_JavaClass, "getZ", "()F"))
}
}
Then on each update cycle you can call the
xValue = JNI.CallFloatMethod(JavaClass, JNI.GetMethodID(cls_JavaClass, "getX", "()F"))
methods to get the current X,Y,Z values respectively. Again this is just pseudocode so it probably won't compile :) But you get the idea.
I'm totally new to Java, but not C#. The above almost makes sense to me, but I can't get it to work. All the JNI stuff and JavaV$$anonymous$$ seems to have been changed (removed) and I had to update the Java code to get it to compile. It ran on my Galaxy tab then crashed, though I didn't mean to run it, but I couldn't find a build command for Java.
Where is the C++ code that reads the java? Would this be easier now with AndroidJNI and AndroidJavaObject helpers in Unity?
I'm trying to access the gyro on my galaxy tab, but Unity says it's not available (and of course, it actually is available), but I have spent the last 8 hours trying to get something working and I am now at a loss, any help in getting the java code into Unity would be really appreciated (preferably without needing Unity Pro, but I sense that is a necessity).
Hey Blitzwing - I'm still trying to get this working. Have a thread in the forum with my code so far. Hoping someone from UT will chime in and answer my questions: http://forum.unity3d.com/threads/100751-Android-Plugin-JNI-Question
Answer by fherbst · Sep 06, 2011 at 04:18 PM
There is a plugin by Prefrontal Cortex in the asset store, which provides access to each and every android sensor. If you don't want to write your own, you could give it a try.
Demo scene (type into your mobiles' browser to install): goo.gl/oLkOQ
Forum thread: http://forum.unity3d.com/threads/101279-GyroDroid-2.0-Access-each-and-every-sensor-on-Android-devices-RELASED
Answer by philo · Apr 11, 2011 at 07:05 AM
I understand (in theory) how this code works, but i can't get the SensorManager to work.
I managed to build the JavaPluginSample project in Eclipse but the game crashes instantly when i include this part of the code:
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
Maybe you can push me in the right direction.
philo
Answer by jsr2k1 · Apr 12, 2011 at 10:22 AM
philo, try this:
public SensorClass(Activity currentActivity)
{
mActivity = currentActivity;
mSensorManager = (SensorManager) mActivity.getSystemService(mActivity.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
mSensorManager.registerListener(mListener, mSensor, SensorManager.SENSOR_DELAY_GAME);
}
I'm having the same issue as Philo. I'm able to compile the .class and .jar file, but when I run it my device it crashes. Did you have to recompile the .cpp and recreate the libjavabridge.so?
Actually I just figured out the crashing issue - I wasn't signing the jar. Looking in the build_plugins.sh showed me all the steps I was missing.
Your answer
Follow this Question
Related Questions
Problem reading sensor plugin, event won't trigger 2 Answers
Now that Unity 4.1.2 broke the Android plugin examples, what do you use to learn them? 1 Answer
UnityPlayerActivity vs. UnityPlayerNativeActivity 0 Answers
Unity 3D Java plugin issues 5 Answers
java android plugin worker thread ends up in Unity mainthread 1 Answer