2010년 8월 16일 월요일

안드로이드 센서 사용하기(Using Sensors in Android)



안드로이드 SDK는 하드웨어에 있는 다양한 센서를 억세스 할 수 있게 해 준다. 현재 기본적으로 지원하는 센서는 다음과 같다.



안드로이드 어플리케이션에서 센서값을 억세스 하려면 SensorManager와 SensorEventListener를 사용한다.

SensorManager sm = (SensorManager)getSystemService(SENSOR_SERVICE);
sm.registerListener(gSensorEventListener, gSensorType, gDelay);

getSystemService(SENSOR_SERVICE)를 사용해 SensorManager 인스턴스를 가져온 다음 SensorEventListener 오브젝트를 등록해주면 센서값을 억세스 할 수 있다.

private void AccSensorEventListener implements SensorEventListener {
  public void onSensorChanged() {
    ...
  }
  public void onAccuracyChanged() {
    ...
  }
}

SensorEventListener 오브젝트에는 onSensorChanged()와 onAccuracyChanged() 메소드를 구현해 줘야 한다. 센서 값이 바뀔때마다 리스너 오브젝트의 onSensorChanged() 메소드가 호출된다.





/src/.../SensorTest.java

...
public class SensorTest extends Activity {
    SensorManager sm;
    SensorEventListener accL;
    SensorEventListener oriL;   
    Sensor oriSensor;
    Sensor accSensor;
    TextView ax, ay, az;
    TextView ox, oy, oz;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
      sm = (SensorManager)getSystemService(SENSOR_SERVICE);    // SensorManager 인스턴스를 가져옴           
        oriSensor = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);    // 방향 센서
        accSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);    // 가속도 센서
        oriL = new oriListener();        // 방향 센서 리스너 인스턴스
        accL = new accListener();       // 가속도 센서 리스너 인스턴스
        ax = (TextView)findViewById(R.id.acc_x);
        ay = (TextView)findViewById(R.id.acc_y);
        az = (TextView)findViewById(R.id.acc_z);
        ox = (TextView)findViewById(R.id.ori_x);
        oy = (TextView)findViewById(R.id.ori_y);
        oz = (TextView)findViewById(R.id.ori_z);
    }
   
    @Override
    public void onResume() {
        super.onResume();
               
        sm.registerListener(accL, accSensor, SensorManager.SENSOR_DELAY_NORMAL);    // 가속도 센서 리스너 오브젝트를 등록
        sm.registerListener(oriL, oriSensor, SensorManager.SENSOR_DELAY_NORMAL);    // 방향 센서 리스너 오브젝트를 등록
    }
   
    @Override
    public void onPause() {
        super.onPause();
       
       sm.unregisterListener(oriL);    // unregister acceleration listener
       sm.unregisterListener(accL);    // unregister orientation listener
    }
   
   
    private class accListener implements SensorEventListener {
        public void onSensorChanged(SensorEvent event) {  // 가속도 센서 값이 바뀔때마다 호출됨
            ax.setText(Float.toString(event.values[0]));
            ay.setText(Float.toString(event.values[1]));
            az.setText(Float.toString(event.values[2]));
            Log.i("SENSOR", "Acceleration changed.");
            Log.i("SENSOR", "  Acceleration X: " + event.values[0]
                          + ", Acceleration Y: " + event.values[1]
                           + ", Acceleration Z: " + event.values[2]);
        }
       
        public void onAccuracyChanged(Sensor sensor, int accuracy) {   
        }       
    }
   
    private class oriListener implements SensorEventListener {
        public void onSensorChanged(SensorEvent event) {  // 방향 센서 값이 바뀔때마다 호출됨
            ox.setText(Float.toString(event.values[0]));
            oy.setText(Float.toString(event.values[1]));
            oz.setText(Float.toString(event.values[2]));
            Log.i("SENSOR", "Orientation changed.");
            Log.i("SENSOR", "  Orientation X: " + event.values[0]
                          + ", Orientation Y: " + event.values[1]
                          + ", Orientation Z: " + event.values[2]);
        }
       
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
           
        }
    }
}




/res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView  android:text="Sensor Values" android:gravity="center" android:textSize="18sp"
        android:layout_width="fill_parent" android:layout_height="wrap_content" />
    <LinearLayout android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
        <TextView android:text="Acceleration(X-axis): "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView android:id="@+id/acc_x"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />   
    </LinearLayout>
    <LinearLayout android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
        <TextView android:text="Acceleration(Y-axis): "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView android:id="@+id/acc_y"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />   
    </LinearLayout>
    <LinearLayout android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
        <TextView android:text="Acceleration(Z-axis): "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView android:id="@+id/acc_z"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />   
    </LinearLayout>
    <View android:layout_width="fill_parent" android:layout_height="4dp" android:background="#ff0000" />
    <LinearLayout android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
        <TextView android:text="Orientation(X-axis): "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView android:id="@+id/ori_x"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />   
    </LinearLayout>
    <LinearLayout android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
        <TextView android:text="Orientation(Y-axis): "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView android:id="@+id/ori_y"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />   
    </LinearLayout>
    <LinearLayout android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
        <TextView android:text="Orientation(Z-axis): "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView android:id="@+id/ori_z"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />   
    </LinearLayout>
   
</LinearLayout>


댓글 10개:

  1. Keep posting stuff like this i really like it

    답글삭제
  2. 좋은 정보 감사드립니다.^^

    덕분에 많은 도움이 되었습니다.^^

    답글삭제
  3. 굿 정보네요 감사

    답글삭제
  4. 좋은 정보 정말 감사합니다.

    답글삭제
  5. 질문하나만해도 될까요??? Sensormanager랑
    SensorEventListener의 역할이 가속도 부분이랑 관련이 있는건가요?
    핸드폰을 가만히 두면 0이 되어야하는거 같은데 자꾸 3축중에 1축은 9가 나와서요 궁금합니다.

    답글삭제
    답글
    1. 어떤 센서를 사용할지는 센서타입에서 지정합니다. 가속도 센서에서 가만히 놔둬도 한축이 값이 나오는 이유는 중력가속도 때문입니다. 지구 중심축 방향쪽으로 중력가속도가 나오게 되죠.

      삭제
  6. 혹시, 딜레이에는 최대값이 몇인지 알 수 있나요?? 펑션을 열어봤는데도 최대값은 명시돼있지 않더라구요. 변화가 너무 빨라서 1초 이상 주고 싶은데, Int형으로 바꿔가며 넣어도 크게 다름을 못 느끼겠더라구요.

    답글삭제
  7. 안녕하세요. if문을 이용해서 x축과 y축이 일정한 값이 되면 다른 레이아웃으로 넘어가는 것을 진행중인데, 센서값이 계속 들어와서 다른 레이아웃이 계속뜨네요 ㅠㅠ 이 루프를 없앨수 있는 방법이 무엇이 있을가요?
    private class accListener implements SensorEventListener {
    public void onSensorChanged(SensorEvent event) { // 가속도 센서 값이 바뀔때마다 호출됨

    ax.setText(Float.toString(event.values[0]));
    ay.setText(Float.toString(event.values[1]));
    az.setText(Float.toString(event.values[2]));

    Log.i("SENSOR", "Acceleration changed.");
    Log.i("SENSOR", " Acceleration X: " + event.values[0]
    + ", Acceleration Y: " + event.values[1]
    + ", Acceleration Z: " + event.values[2]);

    if(event.values[0] < 0.00 && event.values[1] < 0.00){
    Intent intent = new Intent(MainActivity.this, SubActivity.class);
    startActivity(intent);
    }
    }

    답글삭제