Moving an image using Accelerometer of android
Use this code. You were never setting the location of the drawable after you intialized that class. You'll have to do some calculations to set the balls location properly. The way you were doing it was getting values over 10000 which was drawing the oval off screen.
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
public class Accelerometer extends Activity implements SensorEventListener
{
/** Called when the activity is first created. */
CustomDrawableView mCustomDrawableView = null;
ShapeDrawable mDrawable = new ShapeDrawable();
public static int x;
public static int y;
private SensorManager sensorManager = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Get a reference to a SensorManager
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mCustomDrawableView = new CustomDrawableView(this);
setContentView(mCustomDrawableView);
// setContentView(R.layout.main);
}
// This method will update the UI on new sensor events
public void onSensorChanged(SensorEvent sensorEvent)
{
{
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// the values you were calculating originally here were over 10000!
x = (int) Math.pow(sensorEvent.values[1], 2);
y = (int) Math.pow(sensorEvent.values[2], 2);
}
if (sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION) {
}
}
}
// I've chosen to not implement this method
public void onAccuracyChanged(Sensor arg0, int arg1)
{
// TODO Auto-generated method stub
}
@Override
protected void onResume()
{
super.onResume();
// Register this class as a listener for the accelerometer sensor
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
// ...and the orientation sensor
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onStop()
{
// Unregister the listener
sensorManager.unregisterListener(this);
super.onStop();
}
public class CustomDrawableView extends View
{
static final int width = 50;
static final int height = 50;
public CustomDrawableView(Context context)
{
super(context);
mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x, y, x + width, y + height);
}
protected void onDraw(Canvas canvas)
{
RectF oval = new RectF(Accelerometer.x, Accelerometer.y, Accelerometer.x + width, Accelerometer.y
+ height); // set bounds of rectangle
Paint p = new Paint(); // set some paint options
p.setColor(Color.BLUE);
canvas.drawOval(oval, p);
invalidate();
}
}
}
Here is my implementation of this problem. Dymmeh's solution kept throwing problems at me, so I refactored it until I got it working.
package edu.ian495.accelerometertest;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ImageView;
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager sensorManager;
private Sensor accelerometer;
private long lastUpdate;
AnimatedView animatedView = null;
ShapeDrawable mDrawable = new ShapeDrawable();
public static int x;
public static int y;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
accelerometer = sensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
lastUpdate = System.currentTimeMillis();
animatedView = new AnimatedView(this);
setContentView(animatedView);
}
@Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this, accelerometer,
SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
x -= (int) event.values[0];
y += (int) event.values[1];
}
}
public class AnimatedView extends ImageView {
static final int width = 50;
static final int height = 50;
public AnimatedView(Context context) {
super(context);
// TODO Auto-generated constructor stub
mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(0xffffAC23);
mDrawable.setBounds(x, y, x + width, y + height);
}
@Override
protected void onDraw(Canvas canvas) {
mDrawable.setBounds(x, y, x + width, y + height);
mDrawable.draw(canvas);
invalidate();
}
}
}
I have done some changes in onSensorChange code to move the ball in the screen. With the example in my case the ball don´t move correctly and for that I did the changes. This example Works fine for my.
public void onSensorChanged(SensorEvent sensorEvent)
{
//Try synchronize the events
synchronized(this){
//For each sensor
switch (sensorEvent.sensor.getType()) {
case Sensor.TYPE_MAGNETIC_FIELD: //Magnetic sensor to know when the screen is landscape or portrait
//Save values to calculate the orientation
mMagneticValues = sensorEvent.values.clone();
break;
case Sensor.TYPE_ACCELEROMETER://Accelerometer to move the ball
if (bOrientacion==true){//Landscape
//Positive values to move on x
if (sensorEvent.values[1]>0){
//In margenMax I save the margin of the screen this value depends of the screen where we run the application. With this the ball not disapears of the screen
if (x<=margenMaxX){
//We plus in x to move the ball
x = x + (int) Math.pow(sensorEvent.values[1], 2);
}
}
else{
//Move the ball to the other side
if (x>=margenMinX){
x = x - (int) Math.pow(sensorEvent.values[1], 2);
}
}
//Same in y
if (sensorEvent.values[0]>0){
if (y<=margenMaxY){
y = y + (int) Math.pow(sensorEvent.values[0], 2);
}
}
else{
if (y>=margenMinY){
y = y - (int) Math.pow(sensorEvent.values[0], 2);
}
}
}
else{//Portrait
//Eje X
if (sensorEvent.values[0]<0){
if (x<=margenMaxX){
x = x + (int) Math.pow(sensorEvent.values[0], 2);
}
}
else{
if (x>=margenMinX){
x = x - (int) Math.pow(sensorEvent.values[0], 2);
}
}
//Eje Y
if (sensorEvent.values[1]>0){
if (y<=margenMaxY){
y = y + (int) Math.pow(sensorEvent.values[1], 2);
}
}
else{
if (y>=margenMinY){
y = y - (int) Math.pow(sensorEvent.values[1], 2);
}
}
}
//Save the values to calculate the orientation
mAccelerometerValues = sensorEvent.values.clone();
break;
case Sensor.TYPE_ROTATION_VECTOR: //Rotation sensor
//With this value I do the ball bigger or smaller
if (sensorEvent.values[1]>0){
z=z+ (int) Math.pow(sensorEvent.values[1]+1, 2);
}
else{
z=z- (int) Math.pow(sensorEvent.values[1]+1, 2);
}
default:
break;
}
//Screen Orientation
if (mMagneticValues != null && mAccelerometerValues != null) {
float[] R = new float[16];
SensorManager.getRotationMatrix(R, null, mAccelerometerValues, mMagneticValues);
float[] orientation = new float[3];
SensorManager.getOrientation(R, orientation);
//if x have positives values the screen orientation is landscape in other case is portrait
if (orientation[0]>0){//LandScape
//Here I change the margins of the screen for the ball not disapear
bOrientacion=true;
margenMaxX=1200;
margenMinX=0;
margenMaxY=500;
margenMinY=0;
}
else{//Portrait
bOrientacion=false;
margenMaxX=600;
margenMinX=0;
margenMaxY=1000;
margenMinY=0;
}
}
}
}
The view class where I draw the ball
public class CustomDrawableView extends View
{
static final int width = 50;
static final int height = 50;
//Constructor de la figura
public CustomDrawableView(Context context)
{
super(context);
mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x, y, x + width, y + height);
}
//Dibujamos la figura
protected void onDraw(Canvas canvas)
{
//Actividad_Principal x,y,z are variables from the main activity where I have the onSensorChange
RectF oval = new RectF(Actividad_Principal.x+Actividad_Principal.z, Actividad_Principal.y+Actividad_Principal.z, Actividad_Principal.x + width, Actividad_Principal.y + height);
Paint p = new Paint();
p.setColor(Color.BLUE);
canvas.drawOval(oval, p);
invalidate();
}
}
}
That is all, I hope help us.
Try using sensorEvent.values[0]
for your xChange
and sensorEvents.values[1]
for your yChange
if you want to use the acceleration sensor, if not use the same values and move it into the (sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION
) if statement, this will give you the tilt of the handset rather than how quickly its moving along an axis.
You also need to call invalidate();
on the View when you set or change a sensor.
The Sensor.TYPE_ACCELEROMETER
returns:
values[0]: Acceleration minus Gx on the x-axis
values[1]: Acceleration minus Gy on the y-axis
values[2]: Acceleration minus Gz on the z-axis
The Sensor.TYPE_ORIENTATION
returns:
values[0]
: Azimuth, angle between the magnetic north direction and the y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South, 270=West
values[1]
: Pitch, rotation around x-axis (-180 to 180), with positive values when the z-axis moves toward the y-axis.
values[2]
: Roll, rotation around y-axis (-90 to 90), with positive values when the x-axis moves toward the z-axis.