안드로이드(Android) SensorManager SensorEventListener 이용해서 x, y, z 축 감지하는 방법

 

환경: Android Studio

 

스마트폰에는 다양한 센서들이 있습니다. 이 중에서 자력계와 가속도 센서를 이용해 움직임에 대한 정보를 가져올 수 있습니다. 정보를 받아 오기 위해서 SensorEventListener 클래스를 SensorManager 에 등록해야 합니다. 그러면 X, Y, Z 축에 관한 3가지 값을 얻을 수 있습니다. 

 

샘플은 Sensor 에서 받아 온 정보 X, Y, Z 축 값을 화면에 표시합니다. getSystemService(Context.SENSOR_SERVICE) 로 센서 매니저 객체를 받아 온 뒤 onResume() 함수에 자력계와 가속계 센서를 registerListener() 함수로 등록합니다. 그러면 onSensorChanged() 콜백 함수로 스마트폰에 변경이 있을 때 값을 받아 올 수 있습니다. 그리고 getOrientation() 함수에 float 배열을 넘기면 azimut, pitch, roll 값을 넘겨 받을 수 있습니다.

 

l  event.values[0] : Z , azimuth

l  event.values[1] : X , pitch

l  event.values[2] : Y , roll

 

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;

import com.example.sampleandroidinfo.R;

public class SensorEventActivity extends Activity implements
		SensorEventListener {

	private TextView txtAzimuth, txtPitch, txtRoll;
	private static SensorManager mSensorManager;
	private Sensor mAccelerometer; // 가속도 센스
	private Sensor mMagnetometer; // 자력계 센스
	float[] mGravity = null;
	float[] mGeomagnetic = null;
	final float alpha = (float)0.8;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.activity_sensor_event);
		txtAzimuth = (TextView) findViewById(R.id.textzaxis);
		txtPitch = (TextView) findViewById(R.id.textxaxis);
		txtRoll = (TextView) findViewById(R.id.textyaxis);

		mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		mAccelerometer = mSensorManager
				.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		mMagnetometer = mSensorManager
				.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
	}

	@Override
	protected void onPause() {
		super.onPause();
		mSensorManager.unregisterListener(this);
	}

	@Override
	protected void onResume() {
		super.onResume();
		mSensorManager.registerListener(this, mAccelerometer,
				SensorManager.SENSOR_DELAY_UI);
		mSensorManager.registerListener(this, mMagnetometer,
				SensorManager.SENSOR_DELAY_UI);
	}
	
	public void onSensorChanged(SensorEvent event) {
		
		float azimut, pitch, roll;

		if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
			mGravity = event.values;
		} 
		
		if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
			mGeomagnetic = event.values;
		}

		if (mGravity != null && mGeomagnetic != null) {
			float R[] = new float[9];
			float I[] = new float[9];

			boolean success = SensorManager.getRotationMatrix(R, I,
					mGravity, mGeomagnetic);
			if (success) {
				float orientation[] = new float[3];
				SensorManager.getOrientation(R, orientation);
				// orientation contains: azimut, pitch	and roll
				azimut = orientation[0]; 
				pitch = orientation[1];
				roll = orientation[2];
				
				txtAzimuth.setText("x 좌표:" + String.valueOf(azimut));
				txtPitch.setText("y 좌표:" + String.valueOf(pitch));
				txtRoll.setText("z 좌표 : " + String.valueOf(roll));
			}
		}
	}

	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
	}
}

 

메인 Activity 에 들어가는 xml 파일 입니다. X, Y, Z 축을 표시할 TextView 위젯 3개를 추가하였습니다.

 

activity_sensor_event.xml

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#3F0099"
        android:gravity="center"
        android:paddingBottom="@dimen/abc_action_bar_icon_vertical_padding"
        android:paddingTop="@dimen/abc_action_bar_icon_vertical_padding"
        android:text="Sensor 테스트 "
        android:textColor="#FFFFFF" />
	
    <LinearLayout
	    android:layout_width="fill_parent"
	    android:layout_height="fill_parent"
	    android:orientation="vertical" 
	    android:background="#FFCC00"
	    android:padding="20dp">
	    
	    <TextView
	        android:id="@+id/textzaxis"
	        android:layout_width="fill_parent"
	        android:layout_height="wrap_content"
	        android:text="Z 좌표 : " />
	
	    <TextView
	        android:id="@+id/textxaxis"
	        android:layout_width="fill_parent"
	        android:layout_height="wrap_content"
	        android:text="X 좌표 : " />
	
	    <TextView
	        android:id="@+id/textyaxis"
	        android:layout_width="fill_parent"
	        android:layout_height="wrap_content"
	        android:text="Y 좌표 : " />
	
    </LinearLayout>
    
</LinearLayout>

 

안드로이드(Android) SensorManager 와 SensorEventListener 이용해서 x, y, z 축 감지하는 방법

 

Posted by 녹두장군