Search code examples
androidaccelerometer

Accelerometer not changing values


So I have the code below which I can't get to work. I am trying to have one class (AccelerometerReader) read the values of my phone's accelerometer, and then I call those values in another class (MyGame), which I use to print those values on the screen. Everything in the code seems fine, and I don't get any values, except the values that I print all just say 0.0, and don't change. I know for a fact my phone has an accelerometer too. Any help would be appreciated!

Thanks, Owen

AccelerometerReader Class

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;

public class AccelerometerReader extends Activity implements SensorEventListener{
 private SensorManager sensorManager;
 float ax,ay,az;   // these are the acceleration in x, y and z axes

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
   }

   @Override
   public void onAccuracyChanged(Sensor sensor, int accuracy) {
   }

   @Override
   public void onSensorChanged(SensorEvent event) {
       if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
           return;

       if (event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
           ax=event.values[0];
           ay=event.values[1];
           az=event.values[2];
       }
   }


public float getValueX() {
    return ax;
}

public float getValueY() {
    return ay;
}

public float getValueZ() {
    return az;
}
}

Inside MyGame Class

@Override
protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);
    leftWall = new Rect(-100,0,0,canvas.getHeight());
    rightWall = new Rect(canvas.getWidth(), 0, (canvas.getWidth() + 100), canvas.getHeight());
    floor = new Rect(0,canvas.getHeight(),canvas.getWidth(),(canvas.getHeight() + 100));
    ceiling = new Rect(0,-100,canvas.getWidth(),0);

    AccelerometerReader acc = new AccelerometerReader();
    float ax = acc.getValueX();
    float ay = acc.getValueY();
    float az = acc.getValueZ();     

    canvas.drawColor(Color.rgb(red,green,blue)); //0 or 51?, 51, 102

    Rect player = new Rect(xPos,yPos,xPos+100,yPos+100);
    Paint myPaint = new Paint();
    myPaint.setColor(Color.rgb(0, 102, 255));
    canvas.drawRect(player, myPaint);
    myPaint.setColor(Color.rgb(0, 0, 0));
    canvas.drawRect(xPos + 5, yPos + 5, xPos + 95, yPos +95, myPaint);
    myPaint.setColor(Color.WHITE);
    myPaint.setTextSize(20);
    canvas.drawText("" + Math.round(ySpeed), 75, 50, myPaint);
    canvas.drawText(ax +", "+ ay +", "+ az, 300, 50, myPaint);
    if(gameStarted == false) {
        myPaint.setTextSize(30);
        myPaint.setTextAlign(Align.CENTER);
        canvas.drawText("Touch screen to begin!", canvas.getWidth()/2, canvas.getHeight()/2, myPaint);
    }
    int r = Math.round(rand.nextInt(canvas.getHeight() - 150));
    if(needsRand == true) {
        blockY = r;
        myPaint.setColor(Color.rgb(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
    }


    //if(isAlive == true) { 
        Rect block =  new Rect(blockX,blockY,(blockX+100),(blockY+100)); // left, top, right, bottom
        myPaint.setColor(Color.WHITE);
        canvas.drawRect(block, myPaint);
        blockX--;
    //}


    if(player.intersect(leftWall)) {
        xSpeed = Math.abs(xSpeed);
    } else if(player.intersect(rightWall)) { 
        xSpeed = -(xSpeed);
    } else if(player.intersect(floor)) {
        yPos = canvas.getHeight() - 150;
        ySpeed = -(ySpeed)*.75;
    } else if(player.intersect(ceiling)) {
        ySpeed = Math.abs(ySpeed);
    } else if(player.intersect(block)) {
        ySpeed = 0;
    }
    if(blockX <= -100) {
        blockX = canvas.getWidth() + 100;
        needsRand = true;
    } else {
        needsRand = false;
    }

    canvas.drawText("" + r, 300, 100, myPaint);

    physics();
    invalidate();
}

Solution

  • MyService.java

    public class MyService extends Service implements SensorEventListener {
           public void onCreate() {
                  super.onCreate();
                  sm = (SensorManager) getSystemService(SENSOR_SERVICE);
                  sm.unregisterListener(this);  
                  sm.registerListener(this,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_FASTEST);
           }
           public void onDestroy() {
                  super.onDestroy();
                  sm.unregisterListener(this);
           }
    
    // Creates a new binder
    @Override
    public IBinder onBind(Intent intent) {
           return new MyBinder<MyService>(this);
    }
    
    public void onSensorChanged(SensorEvent event) {
           ax=event.values[0];                           
           ay=event.values[1];                           
           az=event.values[2];                
           for (Listener listener : listeners) listener.handleNewAccelValue(this);
    }
    
    public interface Listener {
           // Actions to take when a new position has been added to the model
           void handleNewAccelValue(MyService sender);
    }
    
    // List of all the ongoing listeners bound to the Model
    private List<Listener> listeners = new ArrayList<Listener>();
    
    // Binds a listener from the View to the Model
    public void addListener(Listener listener) {
           this.listeners.add(listener);
    }
    
    // Removes a listener from the View to the Model
    public void removeListener(Listener listener) {
           this.listeners.remove(listener);
    }
    

    YourActivity.java

    public class YourActivity implements MyService.Listener{
    public void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState); 
            // Binds to the created service
            doBindService();
    }
    
    // Creating the controller and the model
    private ServiceComputeFinal controller;
    
    // Creates the connection with a MyService service
    ServiceConnection connection = new ServiceConnection(){
        public void onServiceConnected(ComponentName name, IBinder binder) {
            controller = ((MyBinder<MyService>) binder).getService();           
        }
    
        public void onServiceDisconnected(ComponentName name) {
            controller = null;
        }   
    };
    
    // Binds to the created service
    void doBindService(){
        bindService(new Intent(this, MyService.class), connection, Context.BIND_AUTO_CREATE);
    }
    
    // And finally recover the accelerometer data that interest you
    public void handleNewAccelValue(MyService sender){
        DO_WHATEVER_YOU_WANT_WITH(controller.getAx());
    }
    

    I gave you all the tools to do what you want. Try to look at this code and understand what it does (it's not really complicated), a ServiceConnection allows the Activity to recover values from the Service and the Listener interface allows the Service to notify the Activity when new values are ready. Feel free to ask anything if needed.