한 걸음 두 걸음
android 안드로이드 ] 스마트폰 이동 중인지 정지 상태인지 구분하기/ 가속도센서 활용 본문
반응형
사용 : MainActivity.java & activity_main.xml 두 개만 사용하였음.
activity_main.xml은 간단하기 그지없다. 사실 없어도 되는데
디버깅용 textview 두 개 쓴게 끝이다. 위에 숫자는 이번에 안썼음
package kr.ac.koreatech.swkang.msp02_orientationsensor;
import android.content.Context;
import android.content.Intent;
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.os.Handler;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import static java.lang.StrictMath.abs;
/*이동중 관련은 가속도 (보조) + 스텝 올라가고있음을 감지하는 것(주)로 바꿔!! */
public class MainActivity extends AppCompatActivity implements SensorEventListener {
public ArrayList<Float> sensorValues;
public Handler handler;
//가속도 센서 값
private SensorManager mSensorManger;
private Sensor linearSensor;
//타이머 관련 변수
private long MillisecondTime, StartTime, TimeBuff, UpdateTime = 0L;
private int Seconds, Minutes, MilliSeconds;
//체크용 텍스트뷰
TextView checktext;
TextView checktext2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
//타이머 및 자료수집 시간 실행시킵니다.
handler = new Handler();
StartTime = SystemClock.uptimeMillis();
handler.postDelayed(runnable, 0);
Toast.makeText(getApplicationContext(), "핸들러 시작", Toast.LENGTH_SHORT).show();
}
public boolean isWatching() {
int hitCount = 0;
float sum = 0f;
float Xgap = 0f;
float Ygap = 0f;
float Zgap = 0f;
for(int i = 0; i < 27; i ++){
//첫 번째 레코드와 두 번째 레코드 사이의 차
Xgap = Math.abs(sensorValues.get(i) - sensorValues.get(i+3));
Ygap = Math.abs(sensorValues.get(i+1) - sensorValues.get(i+4));
Zgap = Math.abs(sensorValues.get(i+2) - sensorValues.get(i+5));
//차이의 평균
sum = (Xgap + Ygap + Zgap) / 3.0f;
if(sum < 0.2) hitCount++;
i++; i++;//3의배수대로 i가 늘어나도록 합니다.
}
return hitCount >= 5 ? true : false;
}
public void init() {
mSensorManger = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
linearSensor = mSensorManger.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
mSensorManger.registerListener(this, linearSensor, SensorManager.SENSOR_DELAY_UI);
checktext = (TextView) findViewById(R.id.activity_main_check1); //디버깅중...
checktext2 = (TextView)findViewById(R.id.activity_main_check2);
sensorValues = new ArrayList<>();
}
public Runnable runnable = new Runnable() {
public void run() {
MillisecondTime = SystemClock.uptimeMillis() - StartTime;
UpdateTime = TimeBuff + MillisecondTime;
Seconds = (int) (UpdateTime / 1000);
Minutes = Seconds / 60;
Seconds = Seconds % 60;
MilliSeconds = (int) (UpdateTime % 1000);
//레코드 수가 10개 이상이면 isWatching 함수 실행
if (sensorValues.size() >= 30) {
if(isWatching())
checktext2.setText("정지상태입니다.");
else
checktext2.setText("이동중입니다");
for (int i = 0; i < 15; i++)
sensorValues.remove(0);
}
handler.postDelayed(this, 0);
}
};
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(runnable);
Toast.makeText(getApplicationContext(), "스레드 종료", Toast.LENGTH_SHORT).show();
}
int millCount = 1;
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
//100ms마다 자료를 수집하는 것으로 맞춰주세요~~
if (MilliSeconds / 100 == 0) millCount = 1;
if (sensorEvent.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION && MilliSeconds / 100 >= millCount) {
//가속도 센서값일 경우,
sensorValues.add(sensorEvent.values[0]);
sensorValues.add(sensorEvent.values[1]);
sensorValues.add(sensorEvent.values[2]);
// SensorValues 배열 내부에 X,Y,Z축의 값을 add해줍니다.
millCount++; //100ms마다 한 번씩만 측정하도록 하였습니다.
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
}
참고 논문 : https://pdfs.semanticscholar.org/ded3/9bd2183ad7a73281580b8fb186aacf0f8be7.pdf
http://www.dbpia.co.kr.libproxy.koreatech.ac.kr/journal/articleDetail?nodeId=NODE02370084#none
위의 두 논문을 참고하여 소개된 알고리즘을 사용하였습니다.
반응형
'FrontEnd > Android' 카테고리의 다른 글
Batterystats 데이터 파일 얻는 방법 (0) | 2019.06.12 |
---|---|
Service에서 Activity로 데이터 전달 (0) | 2019.06.12 |
android 안드로이드 ] 실내 실외 구분하기 (0) | 2019.06.11 |
android / 안드로이드 ] LocationListener 내부 오버라이드 함수 (1) | 2019.06.11 |
android 안드로이드 ] 가속도 센서를 통해 움직임 감지하기 (0) | 2019.06.11 |