Search code examples
javaandroidtimeraccelerometerandroid-sensors

Android Accelerometer return same value every time


I'm trying to record 4 sample per second value of accelerometer.So I repeat my logic every 250 millisecond(I have also tried as 4 sampple per second). Every time ends of my method I unregister sensor and register again when my method start(when I'm not unregister the sensor my logic not works in onSensorChanged and it continuously records all data).

By this approach(register and unregister sensor every second or every quarter second) I'm able to mange the sample rate of accelerometer but every time I have return same value.

Here is my onSensorChanged method.

   @Override
    public void onSensorChanged(final SensorEvent event) {

        timer.scheduleAtFixedRate(new TimerTask() {

            @Override
            public void run() {
                            sensorManager.registerListener(JumpingBall.this, accelerometer, sensorManager.SENSOR_DELAY_NORMAL);

                float deltaX1 = (float) ((event.values[0])/9.81);
                float deltaY1 = (float) ((event.values[1])/9.81);
                float deltaZ1 = (float) ((event.values[2])/9.81);

                int i=0;
                for (i=0;i<1;i++) {

                    listx.add(String.valueOf(deltaX1));
                    listy.add(String.valueOf(deltaY1));
                    listz.add(String.valueOf(deltaZ1));
                }
                sensorManager.unregisterListener(JumpingBall.this);

   }


        }, 0, 250);//put here time 1000 milliseconds=1 second\
    }

If any other info needed please inform me.


Solution

  • Don't unregister and register the listener every time. Try to register the listener in your onCreate or onStart methods, and unregister the listener on your onFinish.

    I am pretty sure your errors are coming from the fact that you are seeming to "reset" your accelerometer every time you detect a change.

    In other words, remove your calls

    sensorManager.registerListener(JumpingBall.this, accelerometer, sensorManager.SENSOR_DELAY_NORMAL);

    and

    sensorManager.unregisterListener(JumpingBall.this);

    from your onSensorChanged method and put your sensorManager.registerListener in your main/when you start your context and put your sensorManager.unregisterListener in your onFinished/when you are done with your context.

    https://developer.android.com/guide/topics/sensors/sensors_motion.html

    Here is also a link to some examples of how to set up certain sensors, including the accelerometer. You can see how they initialize the sensors all at the top, and then use onSensorChanged to record the data.

    EDIT:

    Below is what I would do. Make your onSensorChanged still records the event every time the accelerometer senses something, which is what you want to do. MAKE SURE YOU REGISTER YOUR LISTENER IN YOUR onCreate. This is very important. Then, when your timer ticks, make sure that you record the values. Make sure that your variables are available for your onSensorChanged and timer.scheduleAtFixedRate methods by making them package-private (i.e. make sure you initialize them at the top of your class). You also don't need a for loop that only runs once, then its not a loop.

    SO, the idea is read the values always, but only record them every 250ms. As another user pointed out you are also making a new timer every time a new event happens which is not what you want to do. Try implementing the code below:

    //Initialize these up top
    private float deltaX1 = 0;
    private float deltaY1 = 0;
    private float deltaZ1 = 0; 
    
    @Override
    public void onSensorChanged(final SensorEvent event) {
    
                deltaX1 = (float) ((event.values[0])/9.81);
                deltaY1 = (float) ((event.values[1])/9.81);
                deltaZ1 = (float) ((event.values[2])/9.81);
    
    }
    
    
    timer.scheduleAtFixedRate(new TimerTask() {
    
        @Override
        public void run() {
    
            listx.add(String.valueOf(deltaX1));
            listy.add(String.valueOf(deltaY1));
            listz.add(String.valueOf(deltaZ1));
    
        }, 0, 250);//put here time 1000 milliseconds=1 second\
    }
    

    You might have to add the timer code to your onCreate or onStart methods, I am not sure what your project looks like, but implement it where it is appropriate.