티스토리 뷰



이 자료들은 팁스소프트에서 제공하는 [ 알짜배기 ] 프로그램을 이용하면 더 편리하게 볼수 있습니다.
* 알짜배기 프로그램 받기 - http://www.tipssoft.com/bulletin/tb.php/QnA/8406
* 관리자의 Tipssoft 이야기를 들어보세요 ( 트위터 ID : tipssoft )
* 안드로이드 강좌 목록 - http://www.tipssoft.com/bulletin/tb.php/old_bbs/501

터치 형식의 휴대폰을 사용하다보면 통화 화면(액티비티) 상태에서 핸드폰을 귀에 갔다댔을 때 화면이
저절로 꺼지는 것을 볼 수 있습니다. 이것은 휴대폰 액정에 귀가 닿으면서 터치 이벤트가 발생하지
않도록 미연에 방지하기 위한 것입니다. 이러한 기능은 휴대폰의 상단에 있는 근접 센서를 이용하여
휴대폰의 액정과 사물과의 거리를 측정해서 일정 거리 이내의 값이 측정됐을 때 화면을 끄도록 명령을
내려서 구현한 것입니다.
이번 강좌에서는 근접 센서를 이용해서 액정 화면 즉, 기기 화면의 전면에 있는 센서와 사물과의 거리를
측정하는 방법에 대하여 알아보도록 하겠습니다. 센서를 사용할 때 기본적으로 사용되는 공통 루틴에
대하여 잘 모르시는 분들은 아래에 링크된 자료를 먼저 참고하여 주시기 바랍니다.
센서를 사용하기 위한 공통 루틴 : http://www.tipssoft.com/bulletin/tb.php/FAQ/1033
1. 기능 구현하기
센서는 센티미터 단위로 사물과의 거리를 측정합니다. 기본적으로 전달되는 데이터는 하나이며
센서에 따라서 정확한 측정 값이 아닌 "가까운 거리값" 과 "먼 거리값" 둘 중에 하나를 전달하기도
합니다. 여기에서 먼 거리값은 Sensor 클래스의 getMaximumRange 메소드가 반환하는 값이며
해당 값에 미만이 되는 값이 가까운 거리값이 됩니다.
갤럭시S 와 베가 레이서로 테스트했을 때 두 기기 모두 "가까운 거리값"과 "먼 거리값" 만을 반환해
주었으며 각각의 값은 0.0 과 5.0 이었습니다.
센서가 측정한 거리값은 SensorEventListener 인터페이스의 onSensorChanged 메소드의 매개
인자로 전달됩니다. 데이터가 한개이므로 SensorEvent 객체의 values[0] 를 이용하면 됩니다.
아래의 코드는 센서를 이용하여 사물과 센서와의 거리를 측정하는 예제입니다. 근접 센서는 다른
센서들과 달리 화면이 꺼진 상태에서도 지속적으로 거리를 측정해야하므로 onResume / onPause
메소드가 아닌 onStart / onStop 메소드에서 리스너를 등록/해지합니다.
public class TestProximityActivity extends Activity implements SensorEventListener
{
// 센서 관련 객체
SensorManager m_sensor_manager;
Sensor m_sensor;

int m_check_count = 0;
TextView m_check_view;
TextView m_display_view;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// 출력용 텍스트뷰를 얻는다.
m_check_view = (TextView) findViewById(R.id.check_tv);
m_display_view = (TextView) findViewById(R.id.display_tv);

// 시스템서비스로부터 SensorManager 객체를 얻는다.
m_sensor_manager = (SensorManager)getSystemService(SENSOR_SERVICE);
// SensorManager 를 이용해서 근접 센서 객체를 얻는다.
m_sensor = m_sensor_manager.getDefaultSensor(Sensor.TYPE_PROXIMITY);

}

// 해당 액티비티가 시작되면 근접 데이터를 얻을 수 있도록 리스너를 등록한다.
protected void onStart() {
super.onStart();

m_check_count = 0;
// 센서 값을 이 컨텍스트에서 받아볼 수 있도록 리스너를 등록한다.
m_sensor_manager.registerListener(this, m_sensor, SensorManager.SENSOR_DELAY_UI );
}

// 해당 액티비티가 멈추면 근접 데이터를 얻어도 소용이 없으므로 리스너를 해제한다.
protected void onStop() {
super.onStop();
// 센서 값이 필요하지 않는 시점에 리스너를 해제해준다.
m_sensor_manager.unregisterListener(this);
}

// 정확도 변경시 호출되는 메소드. 센서의 경우 거의 호출되지 않는다.
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
}

// 측정한 값을 전달해주는 메소드.
public void onSensorChanged(SensorEvent event)
{
// 정확도가 낮은 측정값인 경우
if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
// 몇몇 기기의 경우 accuracy 가 SENSOR_STATUS_UNRELIABLE 값을
// 가져서 측정값을 사용하지 못하는 경우가 있기때문에 임의로 return ; 을 막는다.
//return;
}
// 센서값을 측정한 센서의 종류가 근접 센서인 경우
if(event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
m_check_count++;
String str;

// 해당 센서가 반환해주는 최대값과 메소드 호출 횟수를 출력한다.
str = "최대치 : " + event.sensor.getMaximumRange() + ", 체크 횟수 : " + m_check_count;
m_check_view.setText(str);
// 데이터 값을 출력한다.
str = "현재 거리 : " + event.values[0];
m_display_view.setText(str);
}
}
}
2. 실행 화면


댓글