Android

안드로이드(android) 가속도 센서(TYPE_ACCELEROMETER) 사용시 onSensorChanged() 호출 속도의 변화

가속도 센서(TYPE_ACCELEROMETER)

요즘 만보기 앱 만든다고 가속도 센서에 대해 공부 중이다. 생각보다 쉽지않다. 하지만 포기할 수 없다.

SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor accelerormeterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

sensorManager.registerListener(this, accelerormeterSensor, SensorManager.SENSOR_DELAY_NORMAL);
센서로 부터 얼마나 자주 결과값을 받을 것인지에 대한 속도를 지정할 수 있다. (샘플링 주기 설정)

public static final int SENSOR_DELAY_FASTEST = 0;
public static final int SENSOR_DELAY_GAME = 1;
public static final int SENSOR_DELAY_NORMAL = 3;
public static final int SENSOR_DELAY_UI = 2;


SensorManager.
SENSOR_DELAY_FASTEST : 가장 빠른 속도
SensorManager.SENSOR_DELAY_GAME : 게임에 적합한 속도
SensorManager.SENSOR_DELAY_NORMAL : 화면 방향 전환에 적당한 속도
SensorManager.SENSOR_DELAY_UI : 사용자 조작을 위해 알맞은 속도

호출속도를 체크하려고 체크를 시도한것은 아니었다.
어느 순간 가속도가 붙으면서 호출속도가 평소에 10배 이상의 튀었기 때문이다.
int sensorCallCnt = 0;

@Override
public void onSensorChanged(SensorEvent event) {

sensorCallCnt = sensorCallCnt + 1;

}

LG G7폰의 경우 1초에 5회 정도 호출하던 속도가 갑자기 1초에 60번 이상 호출하기 시작했다.
만보기 앱을 만들면서 알게된 사실이다.
구글 픽셀2 폰은 1초당 4~5회 샘플링되었고, 가속도가 붙었을 경우 1초당 11회 샘플링 되었다.
삼성폰 갤럭시와이드3(android 9) 의 경우 무조건 1초에 60번 호출한다.
기본 초기 센서 민감도를 측정하였으나 변화가 생긴다면 측정에 정확성이 떨어진다.
Pacer 앱 천만 다운로드 이상 다운로드 된 앱으로 만보기 앱 중에 제일 유명하다.
하지만 이 앱 역시 정확성이 100%는 아님을 알게되었다.

그렇다면 어느순간 속도가  빨라졌는지 여부를 알아내야만 한다.
가속도 센서를 사용하게되면 따라다니는 리턴 받는 onAccuracyChanged()에서 알수 있을까 싶어 로그를 찍어보았다.

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
switch (accuracy) {
case SensorManager.SENSOR_STATUS_UNRELIABLE :
ULog.e(AppSetting.TAG,”##############onAccuracyChanged : Unreliable”);
break;
case SensorManager.SENSOR_STATUS_ACCURACY_LOW:
ULog.e(AppSetting.TAG,”##############onAccuracyChanged : Low Accuracy”);
break;
case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM:
ULog.e(AppSetting.TAG,”##############onAccuracyChanged : Medium Accuracy”);
break;
case SensorManager.SENSOR_STATUS_ACCURACY_HIGH:
ULog.e(AppSetting.TAG,”##############onAccuracyChanged : High Accuracy”);
break;
}
}
}
가속도가 붙던 안붙던 항상 SensorManager.SENSOR_STATUS_ACCURACY_HIGH 값을 리턴받고 있었다.
정확성과 관련되 부분일뿐 가속도증가와는 관계가 없는 것일까?
onAccuracyChanged() 메소드는 신경쓰지 않아도 될 것 같다.

그럼 설마?
아래 값에 따라 변화가 오는 것일까?
public static final int SENSOR_DELAY_FASTEST = 0;
public static final int SENSOR_DELAY_GAME = 1;
public static final int SENSOR_DELAY_NORMAL = 3;
public static final int SENSOR_DELAY_UI = 2;

API를 찾아보니 내가 지정한 샘플링 주기 설정이  변경된다는 것이다.
이벤트가 지정된 속도보다 빠르거나 느려질 수 있습니다. 일반적으로 이벤트가 더 빨리 수신됩니다.

센서 개요

 Note: Don’t use this method with one-shot trigger sensors such as Sensor#TYPE_SIGNIFICANT_MOTION. Use requestTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor) instead.

Parameters

listener SensorEventListener: A SensorEventListener object that will receive the sensor events. If the application is interested in receiving flush complete notifications, it should register with SensorEventListener2 instead.
sensor Sensor: The Sensor to register to.
samplingPeriodUs int: The desired delay between two consecutive events in microseconds. This is only a hint to the system. Events may be received faster or slower than the specified rate. Usually events are received faster. Can be one of SENSOR_DELAY_NORMALSENSOR_DELAY_UISENSOR_DELAY_GAMESENSOR_DELAY_FASTEST or the delay in microseconds.
maxReportLatencyUs int: Maximum time in microseconds that events can be delayed before being reported to the application. A large value allows reducing the power consumption associated with the sensor. If maxReportLatencyUs is set to zero, events are delivered as soon as they are available, which is equivalent to calling registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int).

출처 :https://developer.android.com/reference/android/hardware/SensorManager.html#registerListener(android.hardware.SensorEventListener,%20android.hardware.Sensor,%20int)

센서 딜레이 값을 가져올 수 있는 메소드가 있다. 그 메소드는 Sensor클래스의  getMinDelay()이다.

@Override
public void onSensorChanged(SensorEvent event) {

int minSampleFrequency = accelerormeterSensor.getMinDelay();
int minSampleFrequency = event.sensor.getMinDelay();
int minSampleFrequency = event.sensor.getMaxDelay();

}

하지만 고정된 값만 리턴할 뿐 변화된 값은 보여주지않는다.
찾아야한다..!!!! 방법을!!

데이터 리턴 속도를 체크할 수 있는 메소드는 제공되지않는듯 하다.. 구글링의 한계일 수 도 있다.
나만의 방식으로 처리하였다.
초당 샘플링되는 데이터의 갯수를 체크 후
그에 맞게 데이터 처리를 하였다.

// 1초당 샘플링 주기 체크 카운트 :데이터 샘플링 주기를 체크하기 위함… 1초에 몇회인가
int dataSamplingCount = 0;
String dataSamplingTime =””;

@Override
public void onSensorChanged(SensorEvent event) {

//가속도를 체크한다. (샘플링 주기가 달라지기 때문이다.)
if(dataSamplingTime.equals(DateUtil.GetCurrentFullTime())){
dataSamplingCount++;
}else{
sb.append(“## 1초당 데이터 샘플링 주기 카운트 : ” + dataSamplingCount );
dataSamplingCount = 0; //초기화
}
dataSamplingTime = DateUtil.GetCurrentFullTime();
}

public static String GetCurrentFullTime(){
return new java.text.SimpleDateFormat(“HH:mm:ss”).format(new java.util.Date());
}

이게 완벽한 방법일까?

Leave a Reply

error: Content is protected !!