1

For my Android app I need to get more or less accurately the step count. I say "more or less" because what I need to do is to know if the steps taken in 2 seconds are more or less than the previous ones. I have tried the following two algorithms, and none of them worked effectively. Also I have tested requesting the step count to Google Fit, but it sometimes returns 215, and then 155, so I can't rely on that.

My solutions were as follows:

private SensorEventListener sensorEventListener = new SensorEventListener() {
    //Listens for change in acceleration, displays and computes the steps
    @Override
    public void onSensorChanged(SensorEvent event) {
        //Gather the values from accelerometer
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];

        //Fetch the current y
        currentY = y;

        //Measure if a step was taken
        if(Math.abs(currentY - previousY) > threshold) {
            numSteps++;
            textViewSteps.setText(String.valueOf(numSteps));

            //Vibramos
            Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
            vibrator.vibrate(200);
        }

        //Display the values
        //textViewX.setText(String.valueOf(x));
        //textViewY.setText(String.valueOf(y));
        //textViewZ.setText(String.valueOf(z));

        //Store the previous y
        previousY = y;
    }

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

    }
};

private SensorEventListener sensorEventListener = new SensorEventListener()
{
    private final static String TAG = "StepDetector";
    private float   mLimit = 10;
    private float   mLastValues[] = new float[3*2];
    private float   mScale[] = new float[2];
    private float   mYOffset;

    private float   mLastDirections[] = new float[3*2];
    private float   mLastExtremes[][] = { new float[3*2], new float[3*2] };
    private float   mLastDiff[] = new float[3*2];
    private int     mLastMatch = -1;

    //Como no podemos crear un constructor en una clase anónima, uso un inicializador de instancia (instance initializer)
    {
        int h = 480;
        mYOffset = h * 0.5f;
        mScale[0] = - (h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));
        mScale[1] = - (h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));
    }

    public void setSensitivity(float sensitivity) {
        mLimit = sensitivity; // 1.97  2.96  4.44  6.66  10.00  15.00  22.50  33.75  50.62
    }

    //public void onSensorChanged(int sensor, float[] values) {
    public void onSensorChanged(SensorEvent event) {

        if(calculateKmhtime == 0)
            calculateKmhtime = System.currentTimeMillis();

        Sensor sensor = event.sensor;
        synchronized (this) {
            if (sensor.getType() == Sensor.TYPE_ORIENTATION) {
            }
            else {
                int j = (sensor.getType() == Sensor.TYPE_ACCELEROMETER) ? 1 : 0;
                if (j == 1) {
                    float vSum = 0;
                    for (int i=0 ; i<3 ; i++) {
                        final float v = mYOffset + event.values[i] * mScale[j];
                        vSum += v;
                    }
                    int k = 0;
                    float v = vSum / 3;

                    float direction = (v > mLastValues[k] ? 1 : (v < mLastValues[k] ? -1 : 0));
                    if (direction == - mLastDirections[k]) {
                        // Direction changed
                        int extType = (direction > 0 ? 0 : 1); // minumum or maximum?
                        mLastExtremes[extType][k] = mLastValues[k];
                        float diff = Math.abs(mLastExtremes[extType][k] - mLastExtremes[1 - extType][k]);

                        if (diff > mLimit) {

                            boolean isAlmostAsLargeAsPrevious = diff > (mLastDiff[k]*2/3);
                            boolean isPreviousLargeEnough = mLastDiff[k] > (diff/3);
                            boolean isNotContra = (mLastMatch != 1 - extType);

                            if (isAlmostAsLargeAsPrevious && isPreviousLargeEnough && isNotContra) {
                                Log.i(TAG, "step");

                                //Hemos detectado un paso. Aumentamos el número de pasos
                                numSteps++;
                                textViewSteps.setText(String.valueOf(numSteps));
                                mLastMatch = extType;

                                long currentTime = System.currentTimeMillis();

                                //Vibramos
                                Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
                                vibrator.vibrate(200);

                                if(currentTime - calculateKmhtime >= CALCULATE_KMH_DELAY) {
                                    calculateKmh(stepsInSpecifiedSeconds, (currentTime - calculateKmhtime) / 1000);
                                    calculateKmhtime = System.currentTimeMillis();
                                    stepsInSpecifiedSeconds = 0;
                                }else{
                                    stepsInSpecifiedSeconds++;
                                }
                            }
                            else {
                                mLastMatch = -1;
                            }
                        }
                        mLastDiff[k] = diff;
                    }
                    mLastDirections[k] = direction;
                    mLastValues[k] = v;
                }
            }
        }
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
};

How can it be improved? Thank you

Ernestina Juan
  • 957
  • 1
  • 9
  • 24
  • Google Fit data is more accurate if you use the step count delta. This post may help if you end up going that route: http://stackoverflow.com/questions/29414386/step-count-retrieved-through-google-fit-api-does-not-match-step-count-displayed – blackcj Jul 02 '15 at 14:35
  • Yes, I used it like that, but still isn't accurate for my needs – Ernestina Juan Jul 02 '15 at 14:43
  • FIT API also not giving 100% accurate Result but gives better then other APIs. Appox 10-15% less/more value u get . – Rajesh Satvara Dec 06 '16 at 10:08

0 Answers0