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 _= event.values*;*_

}
else if (type == Sensor.TYPE_MAGNETIC_FIELD) {

for (int i=0 ; i<3 ; i++)
mMData = event.values*;*

}
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, “”, “(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”>


<activity android:name=“.HelloAndroidActivity”
android:label=“@string/app_name”>






Am I missing something obvious?
Is it even possible to make a event based plugin?
Thanks in advance,
Martin

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:

goo.gl/8ZIM7

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]);
    }
}