'Android'에 해당되는 글 3건

  1. 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;

        }

    }



<결과>






화면 회전 소스.zip






'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
And
prev | 1 | 2 | 3 | next