안드로이드 폰은 공간에서 폰의 방향을 감지하기위해 사용되는 방향센서를 가지고 있다. 방향센서는 다음과 같이 세가지 값을 제공한다. 휴대폰을 테이블에 위를 향하게 둔상태에서 앞면이 향한쪽이 values[0] 의 방위각, 비행기가 상승하는것 처럼 상승또는 하강할때 생기는 각이 values[1], 좌우로 기울이게 되면 values[2] 값으로 인식된다.
1. Azimtuh in degres
values[0]값으로 z축을 중심으로 회전한다.
0 ≤ azimuth ≤ 360
2. Pitch in degres
values[1]값으로 x축을 중심으로 회전한다.
-180 ≤ pitch ≤ 180
3. Roll in degres
values[2]값으로 y축을 중심으로 회전한다.
-90 ≤ roll ≤ 90
package net.androgames.blog.sample.orientation; public interface OrientationListener { public void onOrientationChanged(float azimuth, float pitch, float roll); /** * Top side of the phone is up * The phone is standing on its bottom side */ public void onTopUp(); /** * Bottom side of the phone is up * The phone is standing on its top side */ public void onBottomUp(); /** * Right side of the phone is up * The phone is standing on its left side */ public void onRightUp(); /** * Left side of the phone is up * The phone is standing on its right side */ public void onLeftUp(); } |
SensorManager는 지원도는 센서에 대한 정보를 수집하는데 사용된다. 센서서비스를 액세스하거나 사용가능한 센서를 검색하는데 퍼미셔는 요구되지 않는다. 적어도 하나 이상의 센서가 있다면, 리스트의 센서를 위해 SensorEventListener를 등록할 수 있다. 센서 이벤트 감지 간격을 설정하기위해 다음과 같은 상수를 사용할 수 있다.
1. SensorManager.SENSOR_DELAY_FASTEST : as fast as possible
2. SensorManager.SENSOR_DELAY_GAME : rate suitable for game
3. SensorManager.SENSOR_DELAY_NORMAL : normal rate
4. SensorManager.SENSOR_DELAY_UI : rate suitable for UI Thread
방위센서에 대한 예제:
package net.androgames.blog.sample.orientation; import java.util.List; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; /** * Android Orientation Sensor Manager Archetype * @author antoine vianey * under GPL v3 : http://www.gnu.org/licenses/gpl-3.0.html */ public class OrientationManager { private static Sensor sensor; private static SensorManager sensorManager; // 하나 이상의 리스터를 사용하려면 OrientationListener 배열을 사용해도 된다. private static OrientationListener listener; /** Orientation Sensor가 지워되는지 여부 */ private static Boolean supported; /** Orientation Sensor 가 실행중인지 여부 */ private static boolean running = false; /** 폰의 사이드 */ enum Side { TOP, BOTTOM, LEFT, RIGHT; } /** * 매니저가 방위변경을 리스닝하고 있으면 true를 반환 */ public static boolean isListening() { return running; } /** * 리스너 등록 해제 */ public static void stopListening() { running = false; try { if (sensorManager != null && sensorEventListener != null) { sensorManager.unregisterListener(sensorEventListener); } } catch (Exception e) {} } /** * 하나이상의 방위센서가 사용가능하면 true를 반환한다. */ public static boolean isSupported() { if (supported == null) { if (Orientation.getContext() != null) { sensorManager = (SensorManager) Orientation.getContext() .getSystemService(Context.SENSOR_SERVICE); List<Sensor> sensors = sensorManager.getSensorList( Sensor.TYPE_ORIENTATION); supported = new Boolean(sensors.size() > 0); } else { supported = Boolean.FALSE; } } return supported; } /** * 리스너를 등록하고 스타트 시킨다. */ public static void startListening( OrientationListener orientationListener) { sensorManager = (SensorManager) Orientation.getContext() .getSystemService(Context.SENSOR_SERVICE); List<Sensor> sensors = sensorManager.getSensorList( Sensor.TYPE_ORIENTATION); if (sensors.size() > 0) { sensor = sensors.get(0); running = sensorManager.registerListener( sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL); listener = orientationListener; } } /** * 방위센서로부터 발생되는 이벤트를 받아서 처리할 리스너설정 */ private static SensorEventListener sensorEventListener = new SensorEventListener() { /** The side that is currently up */ private Side currentSide = null; private Side oldSide = null; private float azimuth; private float pitch; private float roll; public void onAccuracyChanged(Sensor sensor, int accuracy) {} public void onSensorChanged(SensorEvent event) { azimuth = event.values[0]; // azimuth pitch = event.values[1]; // pitch roll = event.values[2]; // roll if (pitch < -45 && pitch > -135) { // 위를 보고있다. currentSide = Side.TOP; } else if (pitch > 45 && pitch < 135) { // 아래를 보고 있다. currentSide = Side.BOTTOM; } else if (roll > 45) { // 오른쪽이 올라갔다. currentSide = Side.RIGHT; } else if (roll < -45) { // 왼쪽이 올라갔다. currentSide = Side.LEFT; } if (currentSide != null && !currentSide.equals(oldSide)) { switch (currentSide) { case TOP : listener.onTopUp(); break; case BOTTOM : listener.onBottomUp(); break; case LEFT: listener.onLeftUp(); break; case RIGHT: listener.onRightUp(); break; } oldSide = currentSide; } // forwards orientation to the OrientationListener listener.onOrientationChanged(azimuth, pitch, roll); } }; } |
The custom OrientationManager can be use in any Activity or Service :
package net.androgames.blog.sample.orientation; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.widget.TextView; import android.widget.Toast; /** * Android orientation sensor tutorial * @author antoine vianey * under GPL v3 : http://www.gnu.org/licenses/gpl-3.0.html */ public class Orientation extends Activity implements OrientationListener { private static Context CONTEXT; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); CONTEXT = this; } protected void onResume() { super.onResume(); if (OrientationManager.isSupported()) { OrientationManager.startListening(this); } } protected void onDestroy() { super.onDestroy(); if (OrientationManager.isListening()) { OrientationManager.stopListening(); } } public static Context getContext() { return CONTEXT; } @Override public void onOrientationChanged(float azimuth, float pitch, float roll) { ((TextView) findViewById(R.id.azimuth)).setText( String.valueOf(azimuth)); ((TextView) findViewById(R.id.pitch)).setText( String.valueOf(pitch)); ((TextView) findViewById(R.id.roll)).setText( String.valueOf(roll)); } @Override public void onBottomUp() { Toast.makeText(this, "Bottom UP", 1000).show(); } @Override public void onLeftUp() { Toast.makeText(this, "Left UP", 1000).show(); } @Override public void onRightUp() { Toast.makeText(this, "Right UP", 1000).show(); } @Override public void onTopUp() { Toast.makeText(this, "Top UP", 1000).show(); } } |
일반적으로 이스너는 액티비티의 onResume()메서드에 등록하고, onFinish()에서 제거하는것이 적절하다.
이클립스 프로젝트로 볼수 있는 풀소스 링크 : SampleOrientationSensor
Enjoy !
'개발 > 안드로이드' 카테고리의 다른 글
안드로이드로 구글맵 다루기 - 1. 전체 구조 이해 (0) | 2011.08.19 |
---|---|
[안드로이드]Android Sensor - Orientation (0) | 2011.07.19 |
Location Based Service (0) | 2011.07.14 |
[Android] 출력 : 캔버스 (Canvas, Paint) (0) | 2011.06.23 |
[안드로이드] AlarmManager 사용하기 (0) | 2011.06.22 |
댓글