Android

[Java][Android] 안드로이드 가속계(accelerometer)센서, 흔들림 감지 예제

어렵지만 2025. 5. 12. 15:35

1. 개요

안드로이드의 가속도계(Accelerometer) 센서를 이용하면 기기의 움직임, 방향, 흔들림 등을 감지할 수 있습니다.

이 예제에서는 기기가 흔들렸을 때 특정 동작(예: 토스트 메시지 출력)을 실행하는 기본적인 흔들림 감지 앱을 만들어 보겠습니다.

2. 왜 사용할까요??

가속도계를 사용하면 다음과 같은 동작 기반 인터랙션을 구현할 수 있습니다:

  • 기기를 흔들어 기능 실행 (예: 랜덤 뽑기, 새로고침)
  • 사용자의 움직임 감지 (만보기, 피트니스 앱)
  • 게임 컨트롤러로 사용 (기울이기, 흔들기)
  • 보안 기능 (예: 강제 흔들 때 긴급 메시지 전송)

3. 어디에 사용하면 좋을까요???

예시설명
랜덤 추첨 앱 흔들면 결과를 무작위로 선택
QR 스캐너 흔들면 플래시 ON/OFF
메모 앱 흔들면 ‘실수로 지운 항목 복구’
게임 기기를 기울이거나 흔들어서 캐릭터 조작
긴급 SOS 앱 기기를 격하게 흔들면 지정된 번호로 메시지 전송
 

 

4. 어떻게 동작할까요??

핵심 구성요소:

  • SensorManager : 센서 시스템에 접근
  • Sensor.TYPE_ACCELEROMETER : 가속도계 센서
  • SensorEventListener : 센서 이벤트 수신
  • 가속도의 급격한 변화 → 흔들림 판단

 

5. 에뮬레이터에서 테스트하는 법

실제 기기에서는 흔들면 동작하지만, 에뮬레이터에서는 수동 시뮬레이션이 필요합니다.

방법:

  1. 에뮬레이터 오른쪽 도구바 > More 클릭
  2. Sensors > Accelerometer 탭에서 X, Y, Z 값 수동 조정
  3. 빠르게 값 변화 → 흔들림 감지

예제 코드


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.util.Log;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements SensorEventListener {

    SensorManager sensorManager;
    Sensor accelerometer;
    float lastX, lastY, lastZ;
    long lastTime;
    static final int SHAKE_THRESHOLD = 500; // 민감도 조절
    String TAG = "MainActivity";

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

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        if (sensorManager != null) {
            accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        } else {
            Log.d(TAG, "센서매니저 로드 실패하였습니다 값을 확인해주세요! ");
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (accelerometer != null)
            sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

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

    @Override
    public void onSensorChanged(SensorEvent event) {
        long curTime = System.currentTimeMillis();
        Log.d(TAG, "onSensorChanged: curTime 값 :" + curTime);

        if ((curTime - lastTime) > 100) {
            long diffTime = curTime - lastTime;
            lastTime = curTime;

            float x = event.values[0];
            float y = event.values[1];
            float z = event.values[2];

            float speed = Math.abs(x + y + z - lastX - lastY - lastZ) / diffTime * 10000;

            if (speed > SHAKE_THRESHOLD) {
                Toast.makeText(getApplicationContext(), "흔들림 감지됨!", Toast.LENGTH_SHORT).show();
            }

            lastX = x;
            lastY = y;
            lastZ = z;
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // 사용하지 않음
    }
}

 

시연영상