- Home /
Problem reading sensor plugin, event won't trigger
When I run my plugin onSensorChanged won't trigger, leaving me without any information from the sensors.
Here is my Java Class code:
package com.skanska.helloandroid;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
public class HelloAndroidActivity extends Activity implements SensorEventListener{
private SensorManager mSensorManager;
private float[] mGData = new float[3];
private float[] mMData = new float[3];
private float[] mR = new float[16];
private float[] mI = new float[16];
private float[] mOrientation = new float[3];
private Sensor msensor, gsensor;
public float deg = 0;
private String degString;
public HelloAndroidActivity(Activity currentActivity) {
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
gsensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
msensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mSensorManager.registerListener(this, gsensor, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, msensor, SensorManager.SENSOR_DELAY_GAME);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
int type = event.sensor.getType();
if (type == Sensor.TYPE_ACCELEROMETER) {
for (int i=0 ; i<3 ; i++)
mGData[i] = event.values[i];
}
else if (type == Sensor.TYPE_MAGNETIC_FIELD) {
for (int i=0 ; i<3 ; i++)
mMData[i] = event.values[i];
}
else {
return;
}
SensorManager.getRotationMatrix(mR, mI, mGData, mMData);
SensorManager.getOrientation(mR, mOrientation);
final float radtodeg = (float)(180.0f/Math.PI);
deg = mOrientation[0]*radtodeg;
}
public String getDeg(){
degString = Float.toString(deg);
return degString;
}
}
My javabridge(.cpp):
include <stdlib.h>
include <jni.h>
include <android/log.h>
extern "C"
{
JavaVM* java_vm;
jobject HelloAndroidActivity;
jmethodID getDeg;
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
java_vm = vm;
JNIEnv* jni_env = 0;
java_vm->AttachCurrentThread(&jni_env, 0);
jclass cls_Activity = jni_env->FindClass("com/unity3d/player/UnityPlayer");
jfieldID fid_Activity = jni_env->GetStaticFieldID(cls_Activity, "currentActivity", "Landroid/app/Activity;");
jobject obj_Activity = jni_env->GetStaticObjectField(cls_Activity, fid_Activity);
jclass cls_HelloAndroidActivity = jni_env->FindClass("com/skanska/helloandroid/HelloAndroidActivity");
jmethodID mid_HelloAndroidActivity = jni_env->GetMethodID(cls_HelloAndroidActivity, "<init>", "(Landroid/app/Activity;)V");
jobject obj_HelloAndroidActivity = jni_env->NewObject(cls_HelloAndroidActivity, mid_HelloAndroidActivity, obj_Activity);
HelloAndroidActivity = jni_env->NewGlobalRef(obj_HelloAndroidActivity);
getDeg = jni_env->GetMethodID(cls_HelloAndroidActivity, "getDeg", "()Ljava/lang/String;");
return JNI_VERSION_1_6;
}
char* dec = 0;
const char* getDeclination()
{
JNIEnv* jni_env = 0;
java_vm->AttachCurrentThread(&jni_env, 0);
jstring str_dec = (jstring)jni_env->CallObjectMethod(HelloAndroidActivity, getDeg);
jsize stringLen = jni_env->GetStringUTFLength(str_dec);
dec = new char[stringLen+1];
const char* content = jni_env->GetStringUTFChars(str_dec, 0);
strcpy(dec, content);
return dec;
}
}
My C# Call javacode script:
using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
public class CallJavaCode : MonoBehaviour {
[DllImport("javabridge")]
private static extern IntPtr getDeclination();
public float deg;
private string decString;
IntPtr stringPtr = getDeclination();
void Start ()
{
stringPtr=getDeclination();
Debug.Log("stringPtr = " +stringPtr);
String cache = Marshal.PtrToStringAnsi(stringPtr);
Debug.Log("getDeclination returned " + cache);
decString = cache;
deg = float.Parse(decString);
Debug.Log("Deg= " + deg);
transform.eulerAngles = new Vector3(0, 0, deg);
}
void Update()
{
stringPtr = getDeclination();
Debug.Log("stringPtr = " +stringPtr);
String cache = Marshal.PtrToStringAnsi(stringPtr);
Debug.Log("getDeclination returned " + cache);
decString = cache;
deg = float.Parse(decString);
transform.eulerAngles = new Vector3(0, 0, deg);
Debug.Log("Deg = " + deg);
}
void OnGUI ()
{
GUI.Label(new Rect (15, 125, 450, 100), decString);
}
}
I might aswell post my manifest since I have no clue what so ever manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.skanska.helloandroid"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="11" />
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
<activity android:name=".HelloAndroidActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Am I missing something obvious? Is it even possible to make a event based plugin?
Thanks in advance,
Martin
Answer by fherbst · Sep 06, 2011 at 04:14 PM
Instead of writing everything yourself, you could use the GyroDroid plugin by Prefrontal Cortex, it provides access to each and every android sensor an Android device is capable of:
Answer by kristofer_bjorkstrom · Apr 20, 2016 at 08:28 PM
Hello, Very old thread. But anyway I needed the android TYPE_ROTATION_VECTOR sensor. Which one cannot get From Unitys Input eg. Input.acceleration.
So I just wan't to share how I solved it, How to make a nicer solution is up to the reader:) eg. automating the jar, error/exception handling and so on.
In android Studio 1.5.1:
1 create one Android library module (the Android plugin)
2 compile and you will get .aar rename to .zip and extract the classes.jar file
In Unity 5.3.4:
1 put the classes.jar file in the folder Assets/Plugins/Android/classes.jar (NO AndroidManifest.xml seems to be needed for this to work...)
2 Write a Unity script that calls the android plugin functions
Android plugin:
package com.b.rotationsensor;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* Created by kristofer on 2016-04-17.
*/
public class rotationSensor {
private Context context;
private SensorManager mSensorManager;
private Sensor mSensorRot;
private ConcurrentLinkedQueue rotValueQueue;
public rotationSensor() {
Log.d("sensorPlugin", "Instanced");
rotValueQueue = new ConcurrentLinkedQueue();
}
public void setContext(Context context) {
Log.d("sensorPlugin", "Set context");
this.context = context;
}
public void startRotationVector(int intervalMS) {
Log.d("sensorPlugin", "startRotationVector");
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
mSensorRot = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
SensorEventListener mySensorEventListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float sensorData[];
if(event.sensor.getType()== Sensor.TYPE_ROTATION_VECTOR) {
float mMatrix[] = new float[16];
float orientation[] = new float[9];
float mMatrixOut[] = new float[16];
sensorData = event.values.clone();
SensorManager.getRotationMatrixFromVector(mMatrix, sensorData);
SensorManager.remapCoordinateSystem(mMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z , mMatrixOut);
SensorManager.getOrientation(mMatrix, orientation);
sensorData[0] = (float)Math.toDegrees(orientation[0]);
sensorData[1] = (float)Math.toDegrees(orientation[1]);
sensorData[2] = (float)Math.toDegrees(orientation[2]);
// don't let the queue get bigger than 4 sensor readings
if (rotValueQueue.size() == 4) {
rotValueQueue.poll();
}
RotValuesXZY rotValues = new RotValuesXZY();
rotValues.x = sensorData[0];
rotValues.y = sensorData[1];
rotValues.z = sensorData[2];
rotValueQueue.add(rotValues);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
};
mSensorManager.registerListener(mySensorEventListener, mSensorRot, intervalMS);
}
public float[] getRotationVectors () {
float[] rotValuesRet = new float[3];
RotValuesXZY rotValues = (RotValuesXZY)rotValueQueue.poll();
if (rotValues == null) {
return rotValuesRet;
}
rotValuesRet[0] = rotValues.x;
rotValuesRet[1] = rotValues.y;
rotValuesRet[2] = rotValues.z;
return rotValuesRet;
}
}
class RotValuesXZY
{
public float x;
public float y;
public float z;
};
Unity script:
using UnityEngine;
using System.Collections;
public class testJavaPlugin : MonoBehaviour {
private AndroidJavaObject activityContext = null;
private AndroidJavaObject jo = null;
AndroidJavaClass activityClass = null;
void Start () {
activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
activityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
jo = new AndroidJavaObject("com.b.rotationsensor.rotationSensor");
jo.Call("setContext", activityContext);
jo.Call("startRotationVector", 20000);
}
void Update () {
float[] rotVectors = jo.Call<float[]>("getRotationVectors");
Debug.Log("Rotation vector converted to orientation degrees "+ rotVectors[0] +" " + rotVectors[1] + " " + rotVectors[2]);
}
}