Search code examples
androidaccelerometer

Moving an image using Accelerometer of android


I have read articles/tutorial about accessing the phone's accelerometer (acceleration and orientation) values. I am trying to build a simple app where I can move a ball image using the these values. Here is my code:

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.View;
import android.widget.TextView;

public class Accelerometer extends Activity implements SensorEventListener {
    /** Called when the activity is first created. */
     CustomDrawableView mCustomDrawableView = null; 
     ShapeDrawable mDrawable = new ShapeDrawable(); 
      int x ; 
       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) {

         int someNumber = 100;
         float xChange = someNumber * sensorEvent.values[1];
         //values[2] can be -90 to 90
         float yChange = someNumber * 2 * sensorEvent.values[2];       
             x = x + (int)xChange;
             y = y + (int)yChange;

         }


         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 { 

           public CustomDrawableView(Context context) { 
               super(context); 

               int width = 50; 
               int height = 50; 
               mDrawable = new ShapeDrawable(new OvalShape()); 
               mDrawable.getPaint().setColor(0xff74AC23); 
               mDrawable.setBounds(x, y, x + width, y + height); 
           } 
           protected void onDraw(Canvas canvas) { 
               mDrawable.draw(canvas); 
               invalidate(); 
           } 
       }
}

I am getting an oval shape displayed on the screen but nothing happens after that.

thanks


Solution

  • 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();
            }
        }
    }