2021년 1월 24일 일요일

[Android] Android Sensor 센서 프로그래밍

Android Sensor 

https://developer.android.com/guide/topics/sensors/sensors_motion?hl=ko 

현재 안드로이드기기에 들어있는 센서는 3종류로 나뉜다. 레벨14이상이면 다 지원한다.

  • 동작 센서(Motion Sensor)
     x,y,z 3축을 기준으로 기기의 움직임에 의한 가속력과 회전력을 측정해 준다. 운동센서로는 조깅앱, 핸폰들고 푸샵, 균형잡기 앱, 기울기 게임등에 활용할만한 다음과 센서들이 준비되어있다.
    중력 센서(gravity sensor) : 단말의 현재 방향(세워졌던가, 누워있던가)등과 중력(?) 감지
    선형 가속도계(linear accelerometer) : 단말의 이동속도등 감지
    자이로스코프(gyroscope) ,회전 벡터센서(rotational vector sensor): 단말의 회원각을 감지
    중요움직임센서(Use the significant motion sensor) : 걷기,이동,자동차타기 등 위치변화에 큰 움직임등 감지
    걸음걸이관련센서(step detector sensor,step counter sensor) : 몇발자국걸었는지 감지
    등이 있다

  • 위치 센서(Position Sensor)
    단말의 위치에서 측정되는 센서값으로 게임용 회원벡터센서(게임상에서 핸폰의 초기위치를 맞추기 위해 임의로 Y축을 조절하도록 함), 방향센서(나침반센서) , 근접센서(일반적으로 5cm가 넘으면 먼값으로 인정된)등이 있다.

  • 환경 센서(Environment Sensor)
    빛, 온도, 상대습도,기압 등을 감지할수 있다.  

플랫폼별 센서 사용가능여부는 다음과 같다(구글에서 카피페)
https://developer.android.com/guide/topics/sensors/sensors_overview

표 2. 플랫폼별 센서 사용 가능 여부

센서Android 4.0
(API 레벨 14)
Android 2.3
(API 레벨 9)
Android 2.2
(API 레벨 8)
Android 1.5
(API 레벨 3)
TYPE_ACCELEROMETER
TYPE_AMBIENT_TEMPERATURE해당 없음해당 없음해당 없음
TYPE_GRAVITY해당 없음해당 없음
TYPE_GYROSCOPE해당 없음1해당 없음1
TYPE_LIGHT
TYPE_LINEAR_ACCELERATION해당 없음해당 없음
TYPE_MAGNETIC_FIELD
TYPE_ORIENTATION222
TYPE_PRESSURE해당 없음1해당 없음1
TYPE_PROXIMITY
TYPE_RELATIVE_HUMIDITY해당 없음해당 없음해당 없음
TYPE_ROTATION_VECTOR해당 없음해당 없음
TYPE_TEMPERATURE2
예2라고 써있는 것만 지원이 중단되었고, 나머진 14레벨이상이면 다쓸수 있다.


센서에는 측정값을 얻는 공통 인터페이스 함수가 있다.

Public Methods
floatgetMaximumRange()얻을수 있는 최대 측정값
intgetMinDelay()
현재측정값과 다음측정값사이의 최소지연 초ms
StringgetName()센서이름
floatgetPower()전력사용량
floatgetResolution()
센서가 얻을수 있는 해상도(센서의 단위에따라다름)
intgetType()센서타입
StringgetVendor()제조사(센서칩)
intgetVersion()버젼
StringtoString()Returns a string containing a concise, human-readable description of this object.센서에 대한 정보

센서가 반응하는속도(빈도) 설정은 다음과 같다.
반응빈도설정값
SENSOR_DELAY_FASTEST0가장빈번하게 측정 속도
SENSOR_DELAY_GAME1게임에 적합한 측정 속도
SENSOR_DELAY_UI2사용자조작에 맞는 측정 속도
SENSOR_DELAY_NORMAL3일반적인 측정 속도

센서의 측정값(STATUS)에 대해서 신뢰도는 아래와 같이 넘어온다.
신뢰도설정값
SENSOR_STATUS_ACCURACY_HIGH3측정 신뢰도 높음
SENSOR_STATUS_ACCURACY_MEDIUM2측정 신뢰도 보통
SENSOR_STATUS_ACCURACY_LOW1측정 신뢰도 낮음
SENSOR_STATUS_UNRELIABLE0측정 신뢰도 없음



근접센서의 예

퍼미션추가
<uses-permission android:name="android.hardware.sensor.proximity"/>
<application ...>
코드
package com.example.my.proximitysensor;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements SensorEventListener{

private SensorManager sensorManager;
TextView tvProximity;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

tvProximity = (TextView)findViewById(R.id.tvProximity);
sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
Sensor proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
if(proximitySensor == null) {
Toast.makeText(this, "No Proximity Sensor Found", Toast.LENGTH_SHORT).show();
}
}

@Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),
SensorManager.SENSOR_DELAY_NORMAL);
}

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

@Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
if(event.values[0] == 0) {
tvProximity.setText("Near : " + String.valueOf(event.values[0]));
} else {
tvProximity.setText(" Far :" + String.valueOf(event.values[0]));
}
}
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
switch (accuracy) {
case SensorManager.SENSOR_STATUS_UNRELIABLE:
Toast.makeText(this, "UNRELIABLE", Toast.LENGTH_SHORT).show();
break;
case SensorManager.SENSOR_STATUS_ACCURACY_LOW:
Toast.makeText(this, "LOW", Toast.LENGTH_SHORT).show();
break;
case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM:
Toast.makeText(this, "MEDIUM", Toast.LENGTH_SHORT).show();
break;
case SensorManager.SENSOR_STATUS_ACCURACY_HIGH:
Toast.makeText(this, "HIGH", Toast.LENGTH_SHORT).show();
break;
}
}
}

--kotlin--

private var sensorManager: SensorManager? = null


override fun onCreate(savedInstanceState: Bundle?) {

   super.onCreate(savedInstanceState)

   setContentView(R.layout.activity_main)


   sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager

}

override fun onResume() {

   super.onResume()

   sensorManager!!.registerListener(

       this,

       sensorManager!!.getDefaultSensor(Sensor.TYPE_PROXIMITY),

       SensorManager.SENSOR_DELAY_NORMAL

   )

}


override fun onPause() {

   super.onPause()

   sensorManager!!.unregisterListener(this)

}


override fun onSensorChanged(p0: SensorEvent?) {


   if(p0?.sensor?.getType() == Sensor.TYPE_PROXIMITY) {

       if(p0.values[0] == 0f) {

           Log.d("Sensor", p0?.values[0].toString());

       } else {

           Log.d("Sensor", p0?.values[0].toString());

       }

   }


}


override fun onAccuracyChanged(p0: Sensor?, p1: Int) {

   when (p1) {

       SensorManager.SENSOR_STATUS_UNRELIABLE -> Toast.makeText(

           this,

           "UNRELIABLE",

           Toast.LENGTH_SHORT

       ).show()

       SensorManager.SENSOR_STATUS_ACCURACY_LOW -> Toast.makeText(

           this,

           "LOW",

           Toast.LENGTH_SHORT

       ).show()

       SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM -> Toast.makeText(

           this,

           "MEDIUM",

           Toast.LENGTH_SHORT

       ).show()

       SensorManager.SENSOR_STATUS_ACCURACY_HIGH -> Toast.makeText(

           this,

           "HIGH",

           Toast.LENGTH_SHORT

       ).show()

   }


}







0 comments:

댓글 쓰기