I'have written a simple code, that gets accelerometer&orientation meter and display some graphics based on values:
package pl.aadamczyk.enginesdriver;
import android.app.Activity;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
public class EnginesDriverActivity extends Activity implements SensorEventListener
{
private SensorManager sensorManager;
private Sensor accelerometer;
private Sensor orientation;
private Panel panel;
public EnginesDriverActivity()
{
sensorManager = null;
accelerometer = null;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
orientation = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
panel = new Panel(this.getApplicationContext(), null);
setContentView(panel);
}
protected void onResume()
{
super.onResume();
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this, orientation, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause()
{
super.onPause();
sensorManager.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent se)
{
Sensor source = se.sensor;
if (source == accelerometer)
{
System.out.println("Updating orientation: " + se.values[1]);
panel.setOrientation(se.values);
}
else if (source == orientation)
{
System.out.println("Updating TYPE_ACCELEROMETER: " + se.values[1]);
panel.setAccelerometer(se.values);
}
panel.postInvalidate();
}
@Override
public void onAccuracyChanged(Sensor sensor, int arg1)
{
}
}
package pl.aadamczyk.enginesdriver;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class Panel extends View
{
private Paint paint;
private float[] orientation;
private float[] accelerometer;
public Panel(Context context, AttributeSet attrs)
{
super(context, attrs);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
orientation = new float[]{0, 0, 0};
accelerometer = new float[]{0, 0, 0};
}
public void setOrientation(float[] _orientation)
{
orientation = _orientation;
}
public void setAccelerometer(float[] _accelerometer)
{
accelerometer = _accelerometer;
}
@Override
protected void onDraw(Canvas canvas)
{
// Some calculations here
float y = orientation[1];
float z = orientation[2];
System.out.println(y);
// Some graphics here
}
}
The problem is that it's mixing orientation's values with accelerometer's, displaying weird things. There are two System.out.println() in the code - first one in onSensorChanged display good values, but second one in onDraw display orientation or accelerometer value.
How is it possible?
Thanks in advice and sorry for my english.
my guess is that SensorEvent objects get reused by the system. So simply copy the values inOnSensorChanged or your setter methods inside the PanelView
System.arraycopy(ev.values, 0,copy, 0, 3);