'Android'에 해당되는 글 31건
- 2018.05.17 화면 회전을 센서로 체크하기.
샘플용 앱을 개발하다가 다음과 같은 요구사항이 발생했다.
1. 화면은 자동으로 회전되지 않는다.
[특정 기능을 통해 Portrait/landscape 모드를 지원한다.]
2. 물리적으로 화면이 돌아갔을때, 이벤트가 발생되어야 한다.
<그림 예시>
여러가지 방안을 찾아봤지만...
화면을 고정시켜야한 상태에서 이벤트를 받아야하기 때문에 센서를 이용하는 방법외에는 찾지 못했다.
[있을지도 모르는데 일단 찾지는 못 함...]
사용할 센서
Sensor.TYPE_ROTATION_VECTOR ( 또는 Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR 등)
* 센서 사용시에 SensorManager의 getDefaultSensor를 통해서 디바이스가 해당 센서를 제공하는지 체크가 필요하다.
[ 조건문으로 SensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR) != null 를 확인해서 null 인 경우 다른 ROTATION_VECTOR 센서를 사용하자.]
알고리즘 순서
1. 해당 센서의 리스너를 이용해서 roll 과 pitch를 계산한다.
2. 계산된 roll과 pitch 값을 이용하여 이벤트를 발생시킨다.
<roll , pitch>
<코드>
private static final int RADIAN_TO_DEGREE = -57;
//아래 checkOrientation 에서 나오는 값이 라디안 입니다.
//라디안으로 값을 계산하기엔 다소 불편함이 있어 일반적인 도로 단위를 바꿈.
//정확한 값은 57.xxxxxxx 지만 매우 정확한 값을 요구하지 않기 때문에 대략 적인 값을 사용함.
.....
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor == mRotationSensor) {
if (event.values.length > 4) {
float[] truncatedRotationVector = new float[4];
System.arraycopy(event.values, 0, truncatedRotationVector, 0, 4);
checkOrientation(truncatedRotationVector);
} else {
checkOrientation(event.values);
}
}
}
private void checkOrientation(float[] vectors) {
float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrixFromVector(rotationMatrix, vectors);
int axisX = SensorManager.AXIS_X;
int axisZ = SensorManager.AXIS_Z;
float[] adjustedRotationMatrix = new float[9];
SensorManager.remapCoordinateSystem(rotationMatrix, axisX, axisZ, adjustedRotationMatrix);
float[] orientation = new float[3];
SensorManager.getOrientation(adjustedRotationMatrix, orientation);
float azimuch = orientation[0] * RADIAN_TO_DEGREE;
float pitch = orientation[1] * RADIAN_TO_DEGREE;
float roll = orientation[2] * RADIAN_TO_DEGREE;
((TextView)findViewById(R.id.azimuth)).setText("Azimuch: "+azimuch);
((TextView)findViewById(R.id.pitch)).setText("Pitch: "+pitch);
((TextView)findViewById(R.id.roll)).setText("Roll: "+roll);
if(Math.abs(pitch) < 55) { //눕혀있는 경우에는 화면 상태가 어렵다고 판단되어 특정 각도 내에서만 작동하도록 함.
((TextView) findViewById(R.id.orientation)).setText(calculateOrientation((int) roll, (int) pitch));
}
}
private String calculateOrientation(int roll, int pitch) {
if((-120 < roll && roll < -60) || (60 < roll && roll <120)){
return "LANDSCAPE " + roll + "/" + pitch;
}else if(( -30 < roll && roll < 30) || (150 < roll && roll < 180) || (-180 < roll && roll < -150)){
return "PORTRAIT " + roll + "/" + pitch;
}else{
return "UNKNOWN " + roll + "/" + pitch;
}
}
<결과>
'Android > etc' 카테고리의 다른 글
암호화 적용 MessageDigest (0) | 2018.09.14 |
---|---|
Kakao REST API 로컬 연동 (1) | 2018.09.14 |
Android VLC Compile (0) | 2018.02.06 |
화면 코드로 회전 시키기 (0) | 2018.01.23 |
MediaPlayer를 위한 Service 사용 (0) | 2017.12.26 |