본문 바로가기
개발/안드로이드

[안드로이드]방향(Orientation)센서 사용예제

by darksilber 2011. 7. 18.
반응형
출처 - http://cafe.naver.com/sunschool.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=4344&

안드로이드 폰은 공간에서 폰의 방향을 감지하기위해 사용되는 방향센서를 가지고 있다. 방향센서는 다음과 같이 세가지 값을 제공한다. 휴대폰을 테이블에 위를 향하게 둔상태에서 앞면이 향한쪽이 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 !

반응형

댓글