본문 바로가기

ANDROID

[Android] 만보기 만들기

처음에는 가속도 센서로 기울어진 방향에 따라서 걸음을 측정하는 것을 시현했으나 정확도가 너무 떨어졌다.

조금만 기울어도 숫자는 확 바뀌었다. 하지만 이것저것 찾아보니 TYPE_STEP_COUNTER라는 걸음 수 측정 센서가 너무나도 편리하게 존재하고 있었음을 알게 되었다.

 

TYPE_STEP_COUNTER말고 TYPE_STEP_DETECTOR라는 센서도 있는데 이 둘의 차이점을 알아보자.

 

TYPE_STEP_DETECTOR:  리턴 값이 무조건 1, 앱이 종료되면 다시 0부터 시작한다. 

 

TYPE_STEP_COUNTER : 앱 종료와 관계없이 계속 기존의 값을 가지고 있다가 1씩 증가한 값을 리턴한다.

 

만보기는 앱이 꺼진 상태에서도 실행되야한다고 생각했기 때문에 일단 TYPE_STEP_COUNTER를 이용해보았다.

 

사용방법은 매우 간단하다.

 

- TYPE_STEP_COUNTER 센서 이용

 

센서 등록

sensorManager = (SensorManager)getActivity().getSystemService(Context.SENSOR_SERVICE);
stepCountSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);

 

※ 하지만 이 센서는 초기화가 자동으로 되지 않음으로 부가적인 변수를 더 써거 초기화 할 수 있게 코딩해야한다.

참고 사이트 : https://android.googlesource.com/platform/development/+/fb5e574/samples/browseable/BatchStepSensor/src/com.example.android.batchstepsensor/BatchStepSensorFragment.java#141

 

//현재 걸음 수
private int mSteps = 0;
//이전에 저장되있는 값 
private int mCounterSteps = 0;

즉, 이 센서는 초기화가 되지 않기 때문에 현재 걸음 수를 구하려면 이전의 값을 변수에 저장해 두었다가 현재걸음 수를 구할때 그 변수를 빼주어야한다.

 

package org.techtown.walkingresearch;


import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;

import androidx.fragment.app.Fragment;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import static android.content.Context.SENSOR_SERVICE;
import static androidx.core.content.ContextCompat.getSystemService;


/**
 * A simple {@link Fragment} subclass.
 */

//가속도 센서 만보기 계산 API
//-->  https://copycoding.tistory.com/5?category=1014356
public class PedometerFragment extends Fragment implements SensorEventListener{
    Button mReset;
    TextView mwalknum;
    //현재 걸음 수
    private int mSteps = 0;
    //리스너가 등록되고 난 후의 step count
    private int mCounterSteps = 0;


    //센서 연결을 위한 변수
    private SensorManager sensorManager;
    //private Sensor accelerormeterSensor;
    private Sensor stepCountSensor;


    private View view;


    public PedometerFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_pedometer, container, false);

        //센서 연결[걸음수 센서를 이용한 흔듬 감지]
        sensorManager = (SensorManager)getActivity().getSystemService(Context.SENSOR_SERVICE);
        //accelerormeterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        stepCountSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);

        if(stepCountSensor == null){
           // Toast.makeText(this,"No Step Detect Sensor",Toast.LENGTH_SHORT).show();
        }

        mReset = view.findViewById(R.id.reset_btn);
        mwalknum = view.findViewById(R.id.walknum);

        //초기화 버튼 : 다시 숫자를 0으로 만들어준다.
        mReset.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    mSteps = 0;
                    mCounterSteps = 0;
                    mwalknum.setText(Integer.toString(mSteps));

            }
        });


        return view;
    }

    public void onStart() {
        super.onStart();
        if(stepCountSensor !=null){
            //센서의 속도 설정
            sensorManager.registerListener(this,stepCountSensor,SensorManager.SENSOR_DELAY_GAME);
        }
    }
    public void onStop(){
        super.onStop();
        if(sensorManager!=null){
            sensorManager.unregisterListener(this);
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
            if(event.sensor.getType() == Sensor.TYPE_STEP_COUNTER){

               //stepcountsenersor는 앱이 꺼지더라도 초기화 되지않는다. 그러므로 우리는 초기값을 가지고 있어야한다.
                if (mCounterSteps < 1) {
                    // initial value
                    mCounterSteps = (int) event.values[0];
                }
                //리셋 안된 값 + 현재값 - 리셋 안된 값
                mSteps = (int) event.values[0] - mCounterSteps;
                mwalknum.setText(Integer.toString(mSteps));
                Log.i("log: ", "New step detected by STEP_COUNTER sensor. Total step count: " + mSteps );
            }

    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
}