센서 개요

대부분의 Android 지원 기기에는 움직임, 방향, 다양한 환경 조건에서 발생할 수 있습니다. 이러한 센서는 높은 정밀도와 정확도로 원시 데이터를 제공하며 3차원 기기 움직임 또는 위치 지정을 모니터링하거나 기기 근처 주변 환경의 변화를 모니터링하려는 경우에 유용합니다. 예를 들어 게임이 기기의 중력 센서의 측정값을 추적하여 복잡한 사용자 동작을 추론할 수 있음 기울기, 흔들기, 회전 또는 흔들기와 같은 움직임입니다. 마찬가지로 날씨 애플리케이션에서 기기의 온도 센서와 습도 센서를 사용하여 이슬점을 계산하고 보고하거나 여행 애플리케이션에서 지자기장 센서와 가속도계를 사용하여 나침반 방위를 보고할 수 있습니다.

Android 플랫폼은 크게 세 가지 카테고리의 센서를 지원합니다.

  • 움직임 감지 센서

    이 센서는 세 축을 따라 가속력과 회전력을 측정합니다. 이 가속도계, 중력 센서, 자이로스코프 및 회전 벡터가 포함된 카테고리 있습니다.

  • 환경 센서

    이러한 센서는 주변 기온과 같은 다양한 환경 매개변수를 측정합니다. 압력, 조명, 습도입니다. 이 카테고리에는 기압계, 광도계, 있습니다.

  • 위치 센서

    이 센서는 기기의 물리적 위치를 측정합니다. 이 카테고리에는 다음이 포함됩니다. 방향 센서와 자기계가 있습니다.

Android 센서 프레임워크를 사용하여 기기에서 사용 가능한 센서에 액세스하고 원시 센서 데이터를 획득할 수 있습니다. 센서 프레임워크는 다양한 센서 관련 작업을 실행하는 데 도움이 되는 여러 클래스와 인터페이스를 제공합니다. 예를 들어 센서 프레임워크를 사용하여 다음과 같은 작업을 실행할 수 있습니다.

  • 기기에서 사용할 수 있는 센서 확인
  • 최대 범위, 제조업체, 전원 요구사항, 해상도 등 개별 센서의 기능 확인
  • 원시 센서 데이터 획득 및 센서 데이터를 획득하는 최저 속도 정의
  • 센서 변경사항을 모니터링하는 센서 이벤트 리스너를 등록 및 등록 취소

이 주제에서는 Android 플랫폼에서 사용할 수 있는 센서의 개요를 제공합니다. 또한 센서 프레임워크도 소개합니다.

센서 소개

Android 센서 프레임워크를 사용하면 다양한 유형의 센서에 액세스할 수 있습니다. 이러한 센서 중 일부는 하드웨어 기반이고 일부는 소프트웨어 기반입니다. 하드웨어 기반 센서는 빌드된 물리적 구성요소 핸드셋이나 태블릿 장치로 전달할 수 있습니다. 가속도, 지자기장, 각도 변화와 같은 특정 환경 특성을 직접 측정하여 데이터를 얻습니다. 소프트웨어 기반 센서는 하드웨어 기반 센서를 모방하지만 물리적 기기가 아닙니다. 소프트웨어 기반 센서는 하나 이상의 하드웨어 기반 센서에서 데이터를 가져오며 가상 센서 또는 합성 센서라고도 합니다. 선형 가속 센서와 중력 센서는 소프트웨어 기반 센서로 사용되었습니다. 표 1에는 Android에서 지원하는 센서가 요약되어 있습니다. 있습니다.

모든 유형의 센서를 갖춘 Android 지원 기기는 거의 없습니다. 예를 들어 대부분의 휴대전화 기기와 태블릿에는 가속도계와 자기계가 있지만 기압계나 온도계가 있는 기기는 더 적습니다. 또한 한 기기에 동일 유형의 센서가 두 개 이상 있을 수 있습니다. 대상 예를 들어, 기기에는 범위가 다른 두 개의 중력 센서가 있을 수 있습니다.

표 1. Android 플랫폼에서 지원하는 센서 유형

센서 유형 설명 일반적인 용도
TYPE_ACCELEROMETER 하드웨어 중력을 포함하여 세 개의 모든 물리적 축(x, y, z)에서 기기에 적용되는 가속력을 m/s2 단위로 측정합니다. 움직임 감지 (흔들기, 기울이기 등).
TYPE_AMBIENT_TEMPERATURE 하드웨어 주변 상온을 섭씨(°C) 단위로 측정합니다. 아래 내용을 참조하세요. 기온 모니터링.
TYPE_GRAVITY 소프트웨어 또는 하드웨어 모든 기기에서 기기에 가해지는 중력을 m/s2 단위로 측정 3개의 물리적 축 (x, y, z) 움직임 감지 (흔들기, 기울이기 등).
TYPE_GYROSCOPE 하드웨어 세 개의 각 위치를 중심으로 기기의 회전 속도를 rad/s로 측정합니다. 물리적 축 (x, y, z)입니다. 회전 감지(회전, 돌리기 등).
TYPE_LIGHT 하드웨어 주변 조도를 lx 단위로 측정합니다. 화면 밝기 제어.
TYPE_LINEAR_ACCELERATION 소프트웨어 또는 하드웨어 다음과 같은 가속력을 m/s2 단위로 측정합니다. 기기에 적용 3개의 모든 물리적 축(x, y, z)(중력을 제외) 단일 축을 따라 가속도 모니터링.
TYPE_MAGNETIC_FIELD 하드웨어 세 개의 모든 물리적 축(x, y, z) 주변의 지자기장을 μT 단위로 측정합니다. 나침반 만들기.
TYPE_ORIENTATION 소프트웨어 세 개의 모든 물리적 축(x, y, z) 둘레의 기기 회전 각도를 측정합니다. API 수준 3부터 중력 센서와 지자기장 센서를 getRotationMatrix() 메서드와 함께 사용하여 기기의 경사 행렬과 회전 행렬을 얻을 수 있습니다. 기기 위치 확인.
TYPE_PRESSURE 하드웨어 주변 기압을 hPa 또는 mbar 단위로 측정합니다. 기압 변화 모니터링.
TYPE_PROXIMITY 하드웨어 기기의 뷰 화면을 기준으로 객체의 근접도를 cm 단위로 측정합니다. 이 센서는 일반적으로 휴대전화를 귀에 대고 있는지 확인하는 데 사용됩니다. 통화 중 전화 위치.
TYPE_RELATIVE_HUMIDITY 하드웨어 상대 주변 습도를 퍼센트(%) 단위로 측정합니다. 이슬점, 절대 및 상대 습도 모니터링.
TYPE_ROTATION_VECTOR 소프트웨어 또는 하드웨어 기기의 세 가지 요소를 제공하여 기기의 방향을 측정합니다. 회전 벡터입니다. 움직임 감지 및 회전 감지.
TYPE_TEMPERATURE 하드웨어 기기의 온도를 섭씨(°C) 단위로 측정합니다. 이 센서 구현은 기기와 기기에 따라 다르며 이 센서는 다음 위치에서 TYPE_AMBIENT_TEMPERATURE 센서로 교체되었습니다. API 수준 14 온도 모니터링.

센서 프레임워크

Android 센서 프레임워크를 사용하여 이러한 센서에 액세스하고 원시 센서 데이터를 획득할 수 있습니다. 센서 프레임워크는 android.hardware 패키지의 일부이며 다음과 같은 클래스 및 인터페이스를 포함합니다.

SensorManager
이 클래스를 사용하여 센서 서비스의 인스턴스를 만들 수 있습니다. 이 클래스는 센서 액세스 및 나열, 센서 이벤트 리스너 등록 및 등록 취소, 방향 정보 획득을 위한 다양한 방법을 제공합니다. 또한 센서 정확도를 보고하고 데이터 획득 속도를 설정하고 센서를 보정하는 데 사용되는 여러 센서 상수를 제공합니다.
Sensor
이 클래스를 사용하여 특정 센서의 인스턴스를 만들 수 있습니다. 이 클래스는 센서의 기능을 결정할 수 있는 다양한 방법을 제공합니다.
SensorEvent
시스템에서는 이 클래스를 사용하여 센서 이벤트의 정보를 제공하는 센서 이벤트 객체를 만듭니다. 센서 이벤트 객체에는 원시 센서 데이터, 이벤트를 생성한 센서 유형, 데이터의 정확도, 이벤트의 타임스탬프를 비롯한 정보가 포함됩니다.
SensorEventListener
이 인터페이스를 사용하여 센서 값이 변경되거나 센서 정확도가 변경될 때 알림(센서 이벤트)을 수신하는 콜백 메서드를 두 개 만들 수 있습니다.

일반적인 애플리케이션에서는 이러한 센서 관련 API를 사용하여 두 가지 기본 작업을 실행합니다.

  • 센서 및 센서 기능 식별

    런타임에 센서와 센서 기능을 식별하는 것은 애플리케이션이 특정 센서 유형 또는 기능에 의존하는 기능 예를 들어 기기에 존재하는 모든 센서를 식별하고 존재하지 않는 센서에 의존하는 모든 애플리케이션 기능을 사용 중지할 수 있습니다. 마찬가지로 특정 유형의 센서를 모두 식별하여 최적의 애플리케이션 성능을 제공하는 센서 구현을 선택할 수도 있습니다.

  • 센서 이벤트 모니터링

    센서 이벤트 모니터링을 통해 원시 센서 데이터를 획득할 수 있습니다. 센서 이벤트가 매번 발생함 센서는 측정하는 매개변수의 변화를 감지합니다. 센서 이벤트는 이벤트를 트리거한 센서의 이름, 이벤트의 타임스탬프, 이벤트의 정확도, 이벤트를 트리거한 원시 센서 데이터 등 네 가지 정보를 제공합니다.

센서 사용 가능 여부

센서 사용 가능 여부는 기기에 따라 다를 수 있으며 Android 버전 간에도 다를 수 있습니다. 이는 Android 센서가 몇 차례에 걸쳐 도입되어 플랫폼 릴리스와 일치합니다. 예를 들어 많은 센서가 Android 1.5(API 수준 3)에서 도입되었지만 일부 센서는 Android 2.3(API 수준 9)까지 구현되지 않았으며 사용할 수 없었습니다. 마찬가지로 여러 센서가 Android 2.3 (API 레벨 9) 및 Android 4.0 (API 레벨 14)에 도입되었습니다. 2개 센서는 지원 중단되었으며 더 나은 새 센서로 대체되었습니다.

표 2에는 플랫폼별 각 센서의 사용 가능 여부가 요약되어 있습니다. 단 4개 센서 변경사항이 발생한 플랫폼이기 때문입니다. 지원 중단된 것으로 나열된 센서는 Android의 향후 버전과의 호환성 정책에 따라 (기기에 센서가 존재하는 한) 이후 플랫폼에서 여전히 사용할 수 있습니다.

표 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_ORIENTATION 2 2 2
TYPE_PRESSURE 해당 없음1 해당 없음1
TYPE_PROXIMITY
TYPE_RELATIVE_HUMIDITY 해당 없음 해당 없음 해당 사항 없음
TYPE_ROTATION_VECTOR 해당 없음 해당 사항 없음
TYPE_TEMPERATURE 2

1 이 센서 유형은 Android 1.5 (API 수준)에 추가되었습니다. 3) Android 2.3 (API 레벨 9)까지는 사용할 수 없었습니다.

2 이 센서는 사용 가능하지만, 지원 중단되었습니다.

센서 및 센서 기능 식별

Android 센서 프레임워크는 데이터 레이크가 기기에 있는 센서의 런타임입니다. 또한 API는 최대 범위, 해상도, 전력 등 각 센서의 성능 요구사항을 충족해야 합니다

기기에 있는 센서를 식별하려면 먼저 센서 서비스의 참조를 가져와야 합니다. 이렇게 하려면 getSystemService() 메서드를 호출하고 SENSOR_SERVICE 인수를 전달하여 SensorManager 클래스의 인스턴스를 만듭니다. 예를 들면 다음과 같습니다.

Kotlin자바
private lateinit var sensorManager: SensorManager
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

다음으로, getSensorList() 메서드와 TYPE_ALL 상수 사용 예를 들면 다음과 같습니다.

Kotlin자바
val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);

특정 유형의 센서를 모두 나열하려는 경우 TYPE_ALL 대신 TYPE_GYROSCOPE, TYPE_LINEAR_ACCELERATION 또는 TYPE_GRAVITY와 같은 다른 상수를 사용할 수 있습니다.

getDefaultSensor() 메서드를 사용하고 유형을 전달하여 기기에 특정 유형의 센서가 있는지 확인할 수도 있습니다. 상수입니다. 기기에 특정 유형의 센서가 두 개 이상 있는 경우 센서는 기본 센서로 지정되어야 합니다. 동일 센서 유형에 기본 센서가 없는 경우 메서드를 호출하면 null이 반환되며 이는 기기에 해당 유형의 센서가 없다는 것을 의미합니다. 예를 들어 다음 코드는 기기에 자기계가 있는지 확인합니다.

Kotlin자바
private lateinit var sensorManager: SensorManager
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null) {
    // Success! There's a magnetometer.
} else {
    // Failure! No magnetometer.
}
private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){
    // Success! There's a magnetometer.
} else {
    // Failure! No magnetometer.
}

참고: Android에서는 기기 제조업체가 Android 지원 기기에 내장하여 기기는 센서 구성입니다.

기기에 있는 센서를 나열하는 것 외에도 Sensor 클래스를 사용하여 개별 항목의 기능 및 속성을 결정합니다. 있습니다. 이것은 어떤 센서나 통신해야 하는지에 따라 애플리케이션이 다르게 작동하게 하고 싶은 경우에 센서 기능을 기기에서 사용할 수 있습니다. 예를 들어 getResolution()getMaximumRange()를 사용할 수 있습니다. 센서의 해상도와 최대 측정 범위를 얻는 방법입니다. 또한 getPower() 메서드를 사용하여 센서의 전원 요구사항을 가져올 수 있습니다.

공개 메서드 중 두 개는 애플리케이션을 서로 다른 제조업체의 센서 또는 서로 다른 버전의 센서에 최적화하려는 경우에 특히 유용합니다. 예를 들어 애플리케이션에서 기울기 및 흔들기와 같은 사용자 동작을 모니터링해야 하는 경우 특정 공급업체의 중력 센서가 있는 최신 기기용 데이터 필터링 규칙 및 최적화 한 세트를 만들고 중력 센서가 없고 가속도계만 있는 기기용 데이터 필터링 규칙 및 최적화 한 세트를 만들 수 있습니다. 다음 코드 샘플은 getVendor() 메서드와 getVersion() 메서드를 사용하여 실행하는 방법을 보여줍니다. 있습니다. 이 샘플에서는 공급업체가 Google LLC이고 버전 번호가 3인 중력 센서를 찾습니다. 특정 센서가 기기에 없으면 있습니다.

Kotlin자바
private lateinit var sensorManager: SensorManager
private var mSensor: Sensor? = null

...

sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null) {
    val gravSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_GRAVITY)
    // Use the version 3 gravity sensor.
    mSensor = gravSensors.firstOrNull { it.vendor.contains("Google LLC") && it.version == 3 }
}
if (mSensor == null) {
    // Use the accelerometer.
    mSensor = if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
        sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    } else {
        // Sorry, there are no accelerometers on your device.
        // You can't play this game.
        null
    }
}
private SensorManager sensorManager;
private Sensor mSensor;

...

sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = null;

if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){
    List<Sensor> gravSensors = sensorManager.getSensorList(Sensor.TYPE_GRAVITY);
    for(int i=0; i<gravSensors.size(); i++) {
        if ((gravSensors.get(i).getVendor().contains("Google LLC")) &&
           (gravSensors.get(i).getVersion() == 3)){
            // Use the version 3 gravity sensor.
            mSensor = gravSensors.get(i);
        }
    }
}
if (mSensor == null){
    // Use the accelerometer.
    if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){
        mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    } else{
        // Sorry, there are no accelerometers on your device.
        // You can't play this game.
    }
}

또 한 가지 유용한 메서드는 getMinDelay() 메서드입니다. 이 메서드는 센서가 데이터를 감지하는 데 사용할 수 있는 최소 시간 간격(마이크로초)을 반환합니다. getMinDelay() 메서드에 0이 아닌 값을 반환하는 모든 센서는 스트리밍 센서입니다. 스트리밍 센서는 일정한 간격으로 데이터를 감지하며 Android 2.3 (API 레벨 9). getMinDelay() 메서드를 호출할 때 0을 반환하는 센서는 감지 중인 매개변수에 변화가 있을 때만 데이터를 보고하므로 스트리밍 센서가 아닙니다.

getMinDelay() 메서드는 센서가 데이터를 획득할 수 있는 최대 속도를 결정할 수 있기 때문에 유용합니다. 애플리케이션의 특정 기능에 높은 데이터 획득 속도 또는 스트리밍 센서가 필요한 경우 이 메서드를 사용하여 센서가 요구사항을 충족하는지 확인한 다음 애플리케이션의 관련 기능을 적절하게 사용 설정하거나 사용 중지할 수 있습니다.

주의: 센서의 최대 데이터 획득 속도는 센서 프레임워크가 센서 데이터를 애플리케이션에 전달하는 속도입니다. 센서 프레임워크는 센서 이벤트를 통해 데이터를 보고하며 여러 요인이 애플리케이션에서 센서 이벤트를 수신하는 속도에 영향을 미칩니다. 자세한 내용은 센서 이벤트 모니터링을 참조하세요.

센서 이벤트 모니터링

원시 센서 데이터를 모니터링하려면 SensorEventListener 인터페이스를 통해 노출되는 콜백 메서드 두 개, 즉 onAccuracyChanged()onSensorChanged()를 구현해야 합니다. Android 시스템은 이 메서드가 호출될 때마다 이 메서드를 호출합니다.

다음 코드는 onSensorChanged() 메서드를 사용하여 빛 센서입니다. 이 예에서는 TextView에 원시 센서 데이터를 표시합니다. : main.xml 파일에서 sensor_data로 정의됩니다.

Kotlin자바
class SensorActivity : Activity(), SensorEventListener {
    private lateinit var sensorManager: SensorManager
    private var mLight: Sensor? = null

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        // Do something here if sensor accuracy changes.
    }

    override fun onSensorChanged(event: SensorEvent) {
        // The light sensor returns a single value.
        // Many sensors return 3 values, one for each axis.
        val lux = event.values[0]
        // Do something with this sensor value.
    }

    override fun onResume() {
        super.onResume()
        mLight?.also { light ->
            sensorManager.registerListener(this, light, SensorManager.SENSOR_DELAY_NORMAL)
        }
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(this)
    }
}
public class SensorActivity extends Activity implements SensorEventListener {
    private SensorManager sensorManager;
    private Sensor mLight;

    @Override
    public final void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
    }

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Do something here if sensor accuracy changes.
    }

    @Override
    public final void onSensorChanged(SensorEvent event) {
        // The light sensor returns a single value.
        // Many sensors return 3 values, one for each axis.
        float lux = event.values[0];
        // Do something with this sensor value.
    }

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

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

이 예에서는 registerListener() 메서드가 호출될 때 기본 데이터 지연(SENSOR_DELAY_NORMAL)이 지정됩니다. 데이터 지연 (또는 샘플링 레이트)은 센서 이벤트가 애플리케이션으로 전송되는 간격을 제어합니다. onSensorChanged() 콜백 메서드를 통해 호출될 수 있습니다. 기본값 데이터 지연은 모니터링에 적합하며 200,000마이크로초의 지연 시간을 사용합니다. 다른 포드를 지정할 수 있는 SENSOR_DELAY_GAME (20,000마이크로초) 등의 데이터 지연 지연), SENSOR_DELAY_UI (60,000마이크로초 지연), SENSOR_DELAY_FASTEST (0마이크로초 지연 시간) 중에서 선택할 수 있습니다. Android 3.0(API 수준 11)부터 지연 시간을 절대 값(마이크로초 단위)으로 지정할 수도 있습니다.

지정하는 지연은 추천 지연일 뿐입니다. Android 시스템 및 기타 애플리케이션에서 이러한 지연을 변경할 수 있습니다. 가능한 가장 큰 지연을 지정하는 것이 좋습니다. 시스템은 일반적으로 사용자가 지정하는 것보다 더 짧은 지연을 사용합니다. 즉, 가장 느린 샘플링 레이트로도 애플리케이션의 요구사항을 충족할 수 있습니다. 지연 시간을 길게 사용하면 프로세서에 더 낮은 부하가 적용되므로 전력이 더 적게 소모됩니다.

센서 프레임워크가 전송하는 속도를 결정하는 공개 메서드가 없음 센서 이벤트를 애플리케이션에 추가하고 하지만 각 항목과 연결된 타임스탬프를 사용할 수 있습니다. 센서 이벤트를 사용하여 여러 이벤트에 대한 샘플링 레이트를 계산합니다. 포드의 상태를 샘플링 레이트 (지연)를 설정할 수 있습니다. 어떤 이유로든 지연을 변경해야 하는 경우 센서 리스너를 등록 취소하고 다시 등록해야 합니다.

또한 이 예에서는 onResume() 및 센서 이벤트를 등록 및 등록 취소하는 onPause() 콜백 메서드 리스너입니다. 특히 활동이 일시중지된 경우 필요하지 않은 센서를 항상 사용 중지하는 것이 좋습니다. 그렇게 하지 않으면 단 몇 시간에 배터리가 소모될 수 있습니다. 일부 센서에서 상당한 전원이 필요하고 배터리를 빠르게 소모하기 때문입니다. 화면이 꺼져도 시스템이 센서를 자동으로 사용 중지하지 않습니다.

다양한 센서 구성 처리

Android는 기기의 표준 센서 구성을 지정하지 않습니다. 즉, 기기 제조업체는 원하는 모든 센서 구성을 Android 구동 기기 따라서 기기에는 센서로 활용할 수 있습니다 애플리케이션이 특정 유형의 센서에 의존하는 경우 센서가 기기에 존재하여 앱이 실행될 수 있어야 합니다.

특정 센서가 기기에 존재하는지는 두 가지 방법으로 확인할 수 있습니다.

  • 런타임에 센서를 감지하고 애플리케이션 기능을 적절히 사용 설정 또는 중지합니다.
  • Google Play 필터를 사용하여 특정한 센서 구성의 기기를 타겟팅합니다.

각 방법은 다음 섹션에 설명되어 있습니다.

런타임에 센서 감지

애플리케이션이 특정 유형의 센서를 사용하지만 이에 의존하지 않는 경우 런타임에 센서를 감지한 다음 애플리케이션 기능을 사용 중지하거나 사용 설정하는 센서 프레임워크 적절하게 수정할 수 있습니다 예를 들어 내비게이션 애플리케이션에서 온도 센서를 사용할 수 있습니다. 압력 센서, GPS 센서, 지자기장 센서로 온도와 기압을 표시합니다. 압력, 위치 및 나침반 방위 등입니다. 기기에 압력 센서가 없는 경우에는 이를 통해 런타임에 압력 센서의 부재를 감지하고 압력을 표시하는 부분에만 적용됩니다. 예를 들어 다음 코드는 기기에 압력 센서가 있는지 여부:

Kotlin자바
private lateinit var sensorManager: SensorManager
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null) {
    // Success! There's a pressure sensor.
} else {
    // Failure! No pressure sensor.
}
private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){
    // Success! There's a pressure sensor.
} else {
    // Failure! No pressure sensor.
}

Google Play 필터를 사용하여 특정 센서 구성 타겟팅

Google Play에 애플리케이션을 게시하는 경우 매니페스트 파일에 <uses-feature> 요소를 추가하여 지원되지 않는 기기에서 애플리케이션을 필터링합니다. 애플리케이션에 적합한 센서 구성이 있어야 합니다. <uses-feature> 요소에는 특정 센서의 존재 여부를 기반으로 애플리케이션을 필터링할 수 있는 여러 하드웨어 설명자가 있습니다. 가속도계, 기압계, 나침반(지자기장), 자이로스코프, 조도 센서, 근접 센서를 나열할 수 있습니다. 다음은 가속도계가 없는 앱을 필터링하는 매니페스트 항목의 예입니다.

<uses-feature android:name="android.hardware.sensor.accelerometer"
              android:required="true" />

애플리케이션의 매니페스트에 이 요소와 설명자를 추가하면 사용자에게 기기에 가속도계가 있는 경우에만 Google Play에 앱을 표시할 수 있습니다.

애플리케이션이 실행될 때만 설명어를 android:required="true"로 설정해야 합니다. 전적으로 특정 센서에 의존합니다. 애플리케이션이 일부 기능에 센서를 사용하지만 센서 없이 계속 실행되는 경우 <uses-feature>에 센서를 나열해야 합니다. 요소를 포함하지만 설명어를 android:required="false"로 설정합니다. 이렇게 하면 기기에 특정 센서가 없더라도 앱을 설치할 수 있습니다. 이것은 또한 프로젝트 관리 권장사항을 제공합니다. 애플리케이션에서 특정 센서를 사용하지만 여전히 센서 없이 실행되는 경우 런타임에 센서를 감지하고 애플리케이션 기능을 적절히 사용 설정 또는 중지해야 합니다.

센서 좌표계

일반적으로 센서 프레임워크는 표준 3축 좌표계를 사용하여 데이터 값을 표현합니다. 대부분의 센서의 경우 좌표계는 기기가 기본 방향으로 유지될 때 기기의 화면을 기준으로 정의됩니다(그림 1 참고). 기기가 기본 방향으로 유지될 때 X축은 가로축으로 오른쪽을 가리키고 Y축은 세로축으로 위쪽을 가리키며 Z축은 화면 바깥쪽을 가리킵니다. 이 시스템에서 화면 뒤의 좌표는 Z 값이 음수인지 확인합니다 이 좌표계는 다음 센서에서 사용됩니다.

그림 1. 센서에서 사용하는 좌표계 (기기 기준) API에 액세스할 수 있습니다.

이 좌표계를 이해하는 데 있어 가장 중요한 점은 기기의 화면 방향이 변경될 때 축이 바뀌지 않는다는 것입니다. 즉 기기가 움직여도 센서의 좌표계가 변경되지 않습니다. 이 동작은 OpenGL 좌표계의 동작과 동일합니다.

또 다른 이해해야 할 점은 애플리케이션이 기기의 자연스러운 작동을 가정해서는 안 된다는 것입니다. 방향은 세로입니다. 많은 태블릿 기기의 자연스러운 방향은 가로 모드입니다. 또한 센서 좌표계는 항상 기기의 자연스러운 방향을 기준으로 합니다.

마지막으로, 애플리케이션이 센서 데이터를 화면 디스플레이와 일치시키는 경우 getRotation() 메서드를 사용하여 화면 회전을 결정한 다음 매핑할 remapCoordinateSystem() 메서드 센서 좌표를 화면 좌표로 변환합니다. 매니페스트에서 세로 모드 전용 표시를 지정하는 경우에도 이렇게 해야 합니다.

참고: 일부 센서 및 메서드에서는 기기의 기준 좌표계가 아니라 세계 좌표계를 기준으로 하는 좌표계를 사용합니다. 이러한 센서와 메서드는 지구를 기준으로 기기 움직임 또는 기기 위치를 나타내는 데이터를 반환합니다. 자세한 내용은 getOrientation() 메서드, getRotationMatrix() 메서드, 방향 센서, 회전 벡터 센서를 참고하세요.

센서 비율 제한

앱이 다음을 대상으로 하는 경우 사용자에 관한 민감할 수 있는 정보를 보호하기 위해 Android 12 (API 수준 31) 이상에서는 시스템에서 새로고침에 제한을 둡니다. 특정 움직임 감지 센서와 위치 센서의 데이터 속도입니다. 이 데이터 여기에는 장치의 가속도계, 자이로스코프 지자기장 센서를 사용합니다.

새로고침 빈도 제한은 센서 데이터에 액세스하는 방법에 따라 다릅니다.

앱에서 움직임 감지 센서 데이터를 더 빠른 속도로 수집해야 하는 경우 선언한 후에는 HIGH_SAMPLING_RATE_SENSORS 권한을 부여할 수 있습니다. 또는 앱에서 이 권한을 선언하지 않고 더 높은 속도로 움직임 감지 센서 데이터를 수집할 수 있기 때문에 SecurityException이 발생합니다.

AndroidManifest.xml

<manifest ...>
    <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/>
    <application ...>
        ...
    </application>
</manifest>

센서 액세스 및 사용에 관한 권장사항

센서 구현을 설계할 때는 이 섹션에서 확인할 수 있습니다 이 가이드라인은 센서를 사용하는 모든 사용자에게 권장되는 사항입니다. 센서에 액세스하고 센서 데이터를 획득합니다.

포그라운드에서만 센서 데이터 수집

Android 9 (API 수준 28) 이상을 실행하는 기기에서 백그라운드에는 다음과 같은 제한사항이 있습니다.

  • 센서는 연속 가속도계 및 자이로스코프와 같은 보고 모드는 이벤트를 수신합니다.
  • 센서는 변경 시 또는 원샷(one-shot) 보고 모드는 이벤트를 수신하지 않습니다.

이러한 제한사항을 고려하여 앱이 포그라운드에 있거나 포그라운드 서비스의 일부일 때 센서 이벤트를 감지하는 것이 좋습니다.

센서 리스너 등록 취소

센서 사용을 완료했거나 센서 활동이 일시중지된 경우 센서의 리스너를 등록 취소해야 합니다. 센서 리스너가 등록되고 활동이 일시중지된 경우 센서를 등록 취소하지 않는 한 센서에서 계속 데이터를 획득하고 배터리 리소스를 사용합니다. 다음 코드는 onPause() 메서드를 사용하여 리스너를 등록 취소하는 방법을 보여줍니다.

Kotlin자바
private lateinit var sensorManager: SensorManager
...
override fun onPause() {
    super.onPause()
    sensorManager.unregisterListener(this)
}
private SensorManager sensorManager;
...
@Override
protected void onPause() {
    super.onPause();
    sensorManager.unregisterListener(this);
}

자세한 내용은 unregisterListener(SensorEventListener)를 참조하세요.

Android Emulator로 테스트

Android Emulator에는 가속도계, 주변 온도, 자기계, 근접, 조도 등의 센서를 테스트할 수 있는 가상 센서 컨트롤 집합이 포함되어 있습니다.

에뮬레이터는 SdkControllerSensor 있습니다. 이 앱은 Android 4.0 (API)을 실행하는 기기에서만 사용할 수 있습니다. 수준 14) 이상이 필요합니다. (기기에서 Android 4.0을 실행 중인 경우 버전 2가 설치됨) SdkControllerSensor 앱은 기기에서 센서의 변경사항을 모니터링하여 에뮬레이터로 전송합니다. 그런 다음 기기의 센서에서 수신한 새 값을 기반으로 에뮬레이터가 변환됩니다.

SdkControllerSensor 앱의 소스 코드는 다음 위치에 있습니다.

$ your-android-sdk-directory/tools/apps/SdkController

기기와 에뮬레이터 간에 데이터를 전송하려면 다음을 따르세요. 단계:

  1. 기기에서 USB 디버깅이 사용 설정되어 있는지 확인합니다.
  2. USB 케이블을 사용하여 기기를 개발용 컴퓨터에 연결합니다.
  3. 기기에서 SdkControllerSensor 앱을 시작합니다.
  4. 앱에서 에뮬레이션할 센서를 선택합니다.
  5. 다음 adb 명령어를 실행합니다.

  6. $ adb forward tcp:1968 tcp:1968
    
  7. 에뮬레이터를 시작합니다. 이제 기기를 이동하여 에뮬레이터에 변환을 적용할 수 있습니다.

참고: 손으로 움직일 때 에뮬레이터가 변환되지 않는 경우 adb 명령어를 다시 실행합니다.

자세한 내용은 Android 에뮬레이터 가이드를 참조하세요.

onSensorChanged() 메서드를 차단하지 않음

센서 데이터가 빠른 속도로 변경되어 시스템에서 onSensorChanged(SensorEvent) 메서드를 자주 호출할 수도 있습니다. 일반적으로 onSensorChanged(SensorEvent) 메서드 내에서 가능한 한 적게 실행되어 차단되지 않아야 합니다. 애플리케이션에서 데이터를 필터링하거나 센서 데이터를 줄여야 하는 경우 onSensorChanged(SensorEvent) 메서드 밖에서 작업을 실행해야 합니다.

지원 중단된 메서드 또는 센서 유형 사용하지 않음

여러 메서드 및 상수가 지원 중단되었습니다. 특히 TYPE_ORIENTATION는 센서 유형이 지원 중단되었습니다. 방향 데이터를 얻으려면 getOrientation() 메서드를 호출해야 합니다. 마찬가지로 TYPE_TEMPERATURE 센서 유형이 지원 중단되었습니다. 이때 대신 기기의 TYPE_AMBIENT_TEMPERATURE 센서 유형 Android 4.0을 실행하는 앱을 사용하는 것이 좋습니다

센서를 사용하기 전에 확인

센서에서 데이터를 얻으려고 시도하기 전에 항상 기기에 센서가 존재하는지 확인하세요. 단순히 센서가 자주 사용된다고 해서 존재한다고 가정하지 마세요. 기기 제조업체가 자사의 기기에 특정 센서를 제공할 의무는 없습니다.

센서 지연 시간을 신중하게 선택

registerListener() 메서드로 센서를 등록할 때 캠페인에 적합한 전송 속도를 선택해야 합니다. 애플리케이션이나 사용 사례를 정의할 수 있습니다 센서는 매우 빠른 속도로 데이터를 제공할 수 있습니다. 시스템에서 불필요한 추가 데이터를 전송할 수 있도록 하면 시스템 리소스가 낭비되고 배터리 전원이 사용됩니다.