안드로이드 핸드폰 뿐만 아니라 대부분의 이동형 장치는 위치에 따라 기본 방향이 설정되어 있습니다.
이걸 기준으로 화면 자동 회전을 설정해 놓아 사진 가로보기가 가능 합니다.
동서남북을 가리키는 나침반은 방향을 바꾸면 그에 맞추어 위치를 다시 계산해야 합니다.
일반적인 컴퓨터 모니터는 우측상단이 원점이고 가로 방향이 x축, 세로 아래 방향이 y축이지만
Android 기기 에서는 일반적인 수학에서 배운 대로 가로 방향이 x축, 세로 방향이 y축, 나를 향하는 전면 방향을 z축으로 설정 합니다.
좌표 축은 이렇게 설정이 되어 있지만 장치가 세로로 있을 때 우측(가로) 방향이 x축 일까요?
태블릿 장치는 가로로 있을 때 우측 방향이 x축 일까요?
Android를 사용하는 모든 기기가 동일 하지 않다고 하니 방향과 축에 관련된 앱을 개발하려면 한번쯤 확인을 하는게 좋을 듯 합니다.
1. 상수 값
방향 확인을 위해 장치가 어느 방향으로 회전 되어 있는가를 확인하는 상수 값이 있습니다.
Type |
Constants |
value |
설명 |
int |
Surface.ROTATION_0 |
0 |
장치가 사용자 기준 정방향 |
int |
Surface.ROTATION_90 |
1 |
장치가 사용자 기준 반 시계방향 90도 회전 |
int |
Surface.ROTATION_180 |
2 |
장치가 사용자 기준 반 시계방향 180도 회전 |
int |
Surface.ROTATION_270 |
3 |
장치가 사용자 기준 반 시계방향 270도 회전 |
int |
SensorManager.AXIS_X |
1 |
X축에 해당하는 상수 값 |
int |
SensorManager.AXIS_Y |
2 |
Y축에 해당하는 상수 값 |
int |
SensorManager.AXIS_Z |
3 |
Z축에 해당하는 상수 값 |
int |
SensorManager.AXIS_MINUS_X |
129 |
X축 반대 방향에 해당하는 상수 값 |
int |
SensorManager.AXIS_MINUS_Y |
130 |
Y축 반대 방향에 해당하는 상수 값 |
int |
SensorManager.AXIS_MINUS_Z |
131 |
Z축 반대 방향에 해당하는 상수 값 |
2. 회전 결과
먼저 앱을 실행하였을 때의 결과를 보면 간단하게 확인이 가능 합니다.
앱을 켜고 핸드폰을 좌측으로 한 바퀴, 우측으로 한 바퀴 돌리며 결과를 보면
반 시계방향으로 90도씩 증가하는 하며 180도 에서는 어느 방향으로 돌렸는가에 따라
90도, 270도의 결과가 그대로 유지 됩니다.
3. 화면 회전 프로젝트
실제 프로젝트 하나를 만들어 보겠습니다.
3.1 신규 프로젝트 생성
Android studio에서 새로운 프로젝트를 생성합니다. 여기서는 SurfaceRotation로 했습니다.
캡처 화면은 팝업을 축소하여 받은 것으로 실제 화면의 일부분 입니다.
3.2 장치 설정
앱이 실행될 기본 장치를 알맞게 선택 합니다.
3.3 Configure
3.4 Layout 작성
x, y 축의 값을 보여주고 회전 각을 표시하기 위한 TextView를 축의 개수에 맞게 생성 합니다.
<?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="Surface Rotation" 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/tvXaxis" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/tvTitle" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" android:textSize="25dp" android:text="X axis : 0" /> <TextView android:id="@+id/tvYaxis" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/tvXaxis" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" android:textSize="25dp" android:text="Y axis : 0" /> <TextView android:id="@+id/tvZaxis" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/tvYaxis" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" android:textSize="25dp" android:text="Z axis : 0" /> <TextView android:id="@+id/tvRotation" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/tvZaxis" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" android:textSize="25dp" android:text="Rotation : 0" /> </android.support.constraint.ConstraintLayout>
3.5 Java Source
소스는 일반적인 센서 테스트용 프로젝트와 동일한 구조를 갖고 있습니다.
센서는 TYPE_GYROSCOPE를 사용 했는데 별의미 없으므로 다른 센서를 사용해도 됩니다.
화면 회전에 대한 값을 구하기 위한 getSurfaceRotation() 함수가 추가되었습니다.
이 함수에서 화면에 값을 출력 합니다.
package com.example.desk.surfacerotation; import android.app.Activity; import android.content.Context; import android.content.res.Configuration; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Display; import android.view.MotionEvent; import android.view.Surface; import android.view.WindowManager; import android.widget.TextView; public class MainActivity extends AppCompatActivity implements SensorEventListener { private SensorManager sensorManager; private Sensor gyroSensor; int rotation; TextView tvXaxis, tvYaxis, tvZaxis, tvRotation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvXaxis = (TextView)findViewById(R.id.tvXaxis); tvYaxis = (TextView)findViewById(R.id.tvYaxis); tvZaxis = (TextView)findViewById(R.id.tvZaxis); tvRotation = (TextView)findViewById(R.id.tvRotation); sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); gyroSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); } void getSurfaceRotation() { String windowsService = Context.WINDOW_SERVICE; WindowManager windowManager = (WindowManager)getSystemService(windowsService); Display display = windowManager.getDefaultDisplay(); rotation = display.getRotation(); int xAxis = SensorManager.AXIS_X; int yAxis = SensorManager.AXIS_Y; int zAxis = SensorManager.AXIS_Z; switch (rotation) { case Surface.ROTATION_0: tvRotation.setText("Rotation : 0"); break; case Surface.ROTATION_90: xAxis = SensorManager.AXIS_Y; yAxis = SensorManager.AXIS_MINUS_X; tvRotation.setText("Rotation : 90"); break; case Surface.ROTATION_180: yAxis = SensorManager.AXIS_MINUS_Y; tvRotation.setText("Rotation : 180"); break; case Surface.ROTATION_270: xAxis = SensorManager.AXIS_MINUS_Y; yAxis = SensorManager.AXIS_X; tvRotation.setText("Rotation : 270"); break; default: break; } tvXaxis.setText("X axis : " + String.valueOf(xAxis)); tvYaxis.setText("Y axis : " + String.valueOf(yAxis)); tvZaxis.setText("Z axis : " + String.valueOf(zAxis)); } @Override protected void onResume() { super.onResume(); sensorManager.registerListener(this, gyroSensor, SensorManager.SENSOR_DELAY_FASTEST); } @Override public void onSensorChanged(SensorEvent event) { if(event.sensor ==gyroSensor) { getSurfaceRotation(); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }
4. 결과
4.1 결과 화면
위에서 회전각을 표시한 그림과 같은 결과들을 볼 수 있습니다.
3.2 Source Code
소스코드를 첨부 합니다.
3.3 APK File
직접 테스트 하려면 apk를 이용 하세요.
- copy coding -
'Android' 카테고리의 다른 글
안드로이드 가속도 센서 비교 (TYPE_ACCELEROMETER/TYPE_LINEAR_ACCELERATION) (2) | 2018.10.13 |
---|---|
안드로이드 자기장 센서/금속 탐지기 테스트 (TYPE_MAGNETIC_FIELD) (0) | 2018.10.09 |
안드로이드 광 센서 테스트 (TYPE_LIGHT) (0) | 2018.09.27 |
안드로이드 핸드폰 센서 비교 (TYPE_STEP_DETECTOR 와 TYPE_STEP_COUNTER) (2) | 2018.09.15 |
안드로이드 핸드폰 걸음 수 측정 센서 예제 (TYPE_STEP_COUNTER) (4) | 2018.09.14 |