위치 이동이 없는 경우 걸음 횟수를 계산하지 않는 방법을 질문하여 간단하게 테스트를 하여보았습니다.
기존에 올린 글 두개를 섞어서 만들어 보았습니다.
안드로이드 핸드폰
걸음 감지 센서 작동 테스트
(TYPE_STEP_DETECTOR)
안드로이드 GPS를 이용한 속도 측정
소스는 간단 설명하면
1. 걸음 센서 작동 감지
2. 마지막 위치와 현재 위치 사이의 거리 계산
3. 일정 부분 움직인 경우만 걸음 수 계산
이렇게 됩니다.
조금씩 테스트 하면서 거리 값을 수정해야 할 것 같고 필요하면 시간도 포함을 하면 조금 좋은 걸음 수 계산을
할 수 있을 것 같습니다.
1. 걸음 센서 작동 감지 / 3.
걸음 수 계산
TYPE_STEP_DETECTOR가 감지되면 getGPSLocation() 함수를 호출 합니다.
if(longWork > 0.05) 테스트를 위해 거리 이동
감지를 0.05m로 했습니다.
0.05m 이상 이동하면 카운트를 하겠죠
@Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() == Sensor.TYPE_STEP_DETECTOR) {
if(event.values[0] == 1.0f) {
double longWork = getGPSLocation();
if(longWork > 0.05) {
mStepDetector++;
tvStepDetector.setText("Step Detect : " + String.valueOf(mStepDetector));
tvTimeDif.setText("Return 간격 : " + String.format("%.3f",longWork) + " m"); // Time Difference
}
}
}
}
2. 마지막 위치와 현재 위치 사이의 거리 계산
최종 위치와 현재 위치를 이용하여 거리를 계산 합니다.
deltaDist = distance(lat1, lng1,
lat2, lng2);
4. 프로그램 소스
4.1 결과
걸음 감지가 되기 전에는 거리 계산을 하지 않아 모든 값이 공백입니다.
걸음이 감지 되면 기존 위치와 현재 위치를 이용하여 거리를 계산합니다.

핸드폰에서 직접 좌표이용 만보계를 테스트 해보세요.
StepLocation.apk
4.2 AndroidManifest.xml
위치 정보를 사용하기 위한 퍼미션 정보를 설정 합니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="copycoding.tistory.steplocation">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
4.3 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Step Detector Sensor"
android:layout_marginTop="50dp"
android:textSize="30dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvGpsEnable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="GPS Enable :"
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:textSize="25dp"
/>
<TextView
android:id="@+id/tvStepDetector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Step Detect : 0"
app:layout_constraintTop_toBottomOf="@+id/tvGpsEnable"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:textSize="25dp"
/>
<TextView
android:id="@+id/tvGpsLatitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Latitude : "
app:layout_constraintTop_toBottomOf="@+id/tvStepDetector"
android:textSize="20dp"
/>
<TextView
android:id="@+id/tvGpsLongitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Longitude : "
app:layout_constraintTop_toBottomOf="@+id/tvGpsLatitude"
android:textSize="20dp"
/>
<TextView
android:id="@+id/tvEndLatitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="End Latitude : "
app:layout_constraintTop_toBottomOf="@+id/tvGpsLongitude"
android:textSize="20dp"
/>
<TextView
android:id="@+id/tvEndLongitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="End Longitude : "
app:layout_constraintTop_toBottomOf="@+id/tvEndLatitude"
android:textSize="20dp"
/>
<TextView
android:id="@+id/tvTimeDif"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="시간 간격 :"
app:layout_constraintTop_toBottomOf="@+id/tvEndLongitude"
android:textSize="25dp"
/>
<TextView
android:id="@+id/tvDistDif"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="거리 간격 :"
app:layout_constraintTop_toBottomOf="@+id/tvTimeDif"
android:textSize="25dp"
/>
<TextView
android:id="@+id/tvNowLatitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Now Latitude : "
app:layout_constraintTop_toBottomOf="@+id/tvDistDif"
android:textSize="20dp"
/>
<TextView
android:id="@+id/tvNowLongitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Now Longitude : "
app:layout_constraintTop_toBottomOf="@+id/tvNowLatitude"
android:textSize="20dp"
/>
</android.support.constraint.ConstraintLayout>
4.4 MainActivity.java
package copycoding.tistory.steplocation;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements SensorEventListener, LocationListener {
private SensorManager sensorManager;
private Sensor stepDetectorSensor;
TextView tvStepDetector, tvGpsEnable, tvGpsLatitude, tvGpsLongitude, tvTimeDif, tvDistDif, tvEndLatitude, tvEndLongitude, tvNowLatitude, tvNowLongitude;
private int mStepDetector = 0;
private boolean isGPSEnable = false;
private LocationManager locationManager;
private Location lastKnownLocation = null;
private Location nowLastlocation = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//location -------
tvGpsEnable = (TextView)findViewById(R.id.tvGpsEnable);
tvGpsLatitude = (TextView)findViewById(R.id.tvGpsLatitude);
tvGpsLongitude = (TextView)findViewById(R.id.tvGpsLongitude);
tvEndLatitude = (TextView)findViewById(R.id.tvEndLatitude);
tvEndLongitude = (TextView)findViewById(R.id.tvEndLongitude);
tvNowLatitude = (TextView)findViewById(R.id.tvNowLatitude);
tvNowLongitude = (TextView)findViewById(R.id.tvNowLongitude);
tvTimeDif = (TextView)findViewById(R.id.tvTimeDif);
tvDistDif = (TextView)findViewById(R.id.tvDistDif);
//권한 체크
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
// lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
// GPS 사용 가능 여부 확인
isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
tvGpsEnable.setText("GPS Enable: " + isGPSEnable); //GPS Enable
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
//step -----
tvStepDetector = (TextView)findViewById(R.id.tvStepDetector);
sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
stepDetectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
if(stepDetectorSensor == null) {
Toast.makeText(this, "No Step Detect Sensor", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() == Sensor.TYPE_STEP_DETECTOR) {
if(event.values[0] == 1.0f) {
double longWork = getGPSLocation();
if(longWork > 0.05) {
mStepDetector++;
tvStepDetector.setText("Step Detect : " + String.valueOf(mStepDetector));
tvTimeDif.setText("Return 간격 : " + String.format("%.3f",longWork) + " m"); // Time Difference
}
}
}
}
public double getGPSLocation() {
double deltaTime = 0.0;
double deltaDist = 0.0;
//GPS Start
if(isGPSEnable) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return 0.0;
}
// lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(lastKnownLocation == null ) {
lastKnownLocation = nowLastlocation;
}
if (lastKnownLocation != null && nowLastlocation != null) {
double lat1 = lastKnownLocation.getLatitude();
double lng1 = lastKnownLocation.getLongitude();
double lat2 = nowLastlocation.getLatitude();
double lng2 = nowLastlocation.getLongitude();
deltaTime = (nowLastlocation.getTime() - lastKnownLocation.getTime()) / 1000.0; //시간 간격
//double distanceMeter = distance(37.52135327, 126.93035147, 37.52135057, 126.93036593);
deltaDist = distance(lat1, lng1, lat2, lng2);
if(deltaDist > 0.05) {
tvGpsLatitude.setText("Start Latitude : " + lat1);
tvGpsLongitude.setText("Start Longitude : " + lng1);
tvEndLatitude.setText("End Latitude : " + lat2);
tvEndLongitude.setText("End Longitude : " + lng2);
tvDistDif.setText("거리 간격 : " + Double.parseDouble(String.format("%.3f",deltaDist)) + " m"); // Dist Difference
lastKnownLocation = nowLastlocation;
return deltaDist;
}
// lastKnownLocation = nowLastlocation;
}
}
return 0.0;
}
@Override
public void onLocationChanged(Location location) {
nowLastlocation = location;
Toast.makeText(this, "Locatiuon Changed", Toast.LENGTH_SHORT).show();
double lng = location.getLongitude();
double lat = location.getLatitude();
Log.d("Now Location ::::::", "longtitude=" + lng + ", latitude=" + lat);
tvNowLatitude.setText("Now Latitude : " + lat);
tvNowLongitude.setText("Now Longitude : " + lng);
}
@Override
public void onProviderEnabled(String provider) {
//권한 체크
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
// 위치정보 업데이트
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,0, this);
}
@Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this, stepDetectorSensor, SensorManager.SENSOR_DELAY_UI);
//권한 체크
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
// 위치정보 업데이트
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,0, this);
}
@Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
// 위치정보 가져오기 제거
locationManager.removeUpdates(this);
}
@Override
protected void onStart() {
super.onStart();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//권한이 없을 경우 최초 권한 요청 또는 사용자에 의한 재요청 확인
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION) &&
ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
// 권한 재요청
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 100);
return;
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 100);
return;
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
// 거리계산
private static double distance(double lat1, double lon1, double lat2, double lon2) {
double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
dist = Math.acos(dist);
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
dist = dist * 1.609344 * 1000; //미터 단위
return dist;
}
// This function converts decimal degrees to radians
private static double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
// This function converts radians to decimal degrees
private static double rad2deg(double rad) {
return (rad * 180 / Math.PI);
}
}
- copy coding -