Android/센서 | Posted by 덩치 2014.01.07 10:36

기본적인 센서(Sensor) 사용법

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

1. 클래스에 SensorEventListener 참조설정

2. onResume에서 센서값 받아오는 딜레이 설정

3. 리스너가 읽어들이는 센서값 판별, 활용


public class MainActivity extends Activity implements SensorEventListener {

SensorManager sm;

Sensor gyroSensor;

@Override

protected void onCreate(Bundle saveInstanceState) {

sm =  = (SensorManager) getSystemService(SENSOR_SERVICE);

//4가지 센서 설정

gyroSensor = sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE);

accSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

magSensor = sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

oriSensor = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);

}

//액티비티에 SensorEventListener를 참조하게 되면 Add unimplemented methods를 통해 밑의 항목을 오버라이드한다.

@Override

protected void onResume() {

super.onResume();

//4가지 센서에 대한 딜레이 설정. 이걸 해 줘야 리스너로 값이 떨어짐

sm.registerListener(this, gyroSensor, SensorManager.SENSOR_DELAY_UI);

sm.registerListener(this, accSensor , SensorManager.SENSOR_DELAY_UI);

sm.registerListener(this, magSensor, SensorManager.SENSOR_DELAY_UI);

sm.registerListener(this, oriSensor , SensorManager.SENSOR_DELAY_UI);

}

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

//정확도 변경시 사용된다는것 같은데 정확한 용도는 잘 모르겠다. 사용되는건 한번도 못 본듯 하다.

}

@Override

public void onSensorChanged(SensorEvent event) {

//여기서 센서값이 변하는걸 체크한다.

switch (event.sensor.getType()) {

case Sensor.TYPE_GYROSCOPE :

Log.d("tag", "TYPE_GYROSCOPE");

break;

case Sensor.TYPE_ACCELEROMETER :

Log.d("tag", "TYPE_ACCELEROMETER");

break;

//등등으로 쭉 나간다.

}

}

}


센서의 값을 확인하는 방법은 case절 안에서

event.values[0] , event.values[1] , event.values[2] 를 출력하면 x,y,z축의 값이 출력된다.

Log.d("tag", "" + event.values[0]); 이런식으로 ..


이상으로 간단한 센서 사용법을 알아보았다.

문의사항이나 태클걸만한게 있다면 언제든지 댓글 남겨주시길.

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

기본적인 셋팅은 이전에 방위센서에서 다뤘으므로 주석없이 술술 나가겠음


float[] gravity_data = new float[3];

float[] accel_data = new float[3];

float[] m_acc_data = new float[3];

 final float alpha = (float)0.8;


SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);

Sensor mSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);


protected void onResume(){

super.onResume();

sm.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_UI);

}


public void onDestroy(){

super.onDestroy();

sm.unregisterListener(this);

}


@Override

public void onSensorChanged(SensorEvent event) {

if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

gravity_data[0] = alpha * gravity_data[0] + (1 - alpha) * event.values[0]; //먼저 중력데이터를 계산함

gravity_data[1] = alpha * gravity_data[1] + (1 - alpha) * event.values[1];

gravity_data[2] = alpha * gravity_data[2] + (1 - alpha) * event.values[2];

accel_data[0] = event.values[0] - gravity_data[0]; // 순수 가속도센서값에 중력값을 빼줌

accel_data[1] = event.values[1] - gravity_data[1]; // 아니면 약 9.81 어쩌고 하는값이 더해짐

accel_data[2] = event.values[2] - gravity_data[2];

tv1.setText("x축 : " + accel_data[0]);

tv2.setText("y축 : " + accel_data[1]);

tv3.setText("z축 : " + accel_data[2]);

}

}


빼먹은게 있을수도 있지만, 알맹이는 다 들어있습니다. 문의는 댓글로

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

가장 기본적이면서 중요한 메커니즘은 SensorEventListener 참조, onResume에서 딜레이 설정이다.


//먼저 액티비티에 SensorEventListener을 implements 해 준다.

public class MainActivity extends Activity implements SensorEventListener{

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);


float[] rotation = new float[9];  

float[] result_data = new float[3];

float[] mag_data = new float[3]; //센서데이터를 저장할 배열 생성 

float[] acc_data new float[3]; //가속도데이터값이 들어갈 배열. 각도를 뽑으려면 가속도와 지자계의 값이 있어야함.

크기가 3인 이유는 센서값 values의 index가 3이기때문(x.y.z)


SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE); //센서매니저 생성

mag_sensor = sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); //마그네틱 필드 센서 생성

}

//센서 읽어들이는 간격 설정(NORMAL < UI < GAME 순 속도)

protected void onResume(){

super.onResume();

sm.registerListener(this, mag_sensor, SensorManager.SENSOR_DELAY_UI);

}



@Override

public void onSensorChanged(SensorEvent event) {  //센서값 변경을 읽는 리스너

if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)   //센서가 읽어들인 값이 마그네틱필드일때

mag_data = event.values.clone();    //데이터를 모두 mag_data 배열에 저장

if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) // 가속도센서값일때

acc_data = event.values.clone();  //마찬가지

if (mag_data != null && acc_data != null) { //널체크    

       SensorManager.getRotationMatrix(rotation, null, acc_data, mag_data); //회전메트릭스 연산

             SensorManager.getOrientation(rotation, result_data); //연산값으로 방향값 산출

result_data[0] = (float)Math.toDegrees(result_data[0]); // 방향값을 각도로 변환

if(result_data[0] < 0) m_result_data[0] += 360; //0보다 작을경우 360을더해줌

}

}



//종료시에는 반드시 센서의 리스너를 해제해줘야함

public void onDestroy(){

super.onDestroy();

sm.unregisterListener(this);

}


}


빠진부분이나 의문사항 댓글로 남겨주면 답변드립니다.