스타벅스 어플에는 Shake Pay라는 기능이 있다. Shake Pay는 계정에 스타벅스 카드를 등록한 경우 앱에서 디바이스를 흔들면 등록한 카드의 바코드가 생성되어 결제할 수 있는 기능이다. 단순히 신기함에서 넘어갈 수도 있지만 이를 응용하여 흔들면 결제 바코드 화면으로 전환되는 기능을 한번 만들어 보았다.
동작 원리
안드로이드에서는 많은 센서를 지원하는 데 그중 하나인 SensorEventListener 클래스가 있는데 이게 바로 Shake Pay의 핵심이다. Shake Pay를 실행하려는 Activity에 SensorEventListener 인터페이스를 상속하여 가속도 감지 및 외부의 충격량과 방향 감지를 해서 이벤트를 발생시킨다.
- SensorEventListener란?
SensorEventListener는 센서 값이 변경되었을 때 SensorManager에게 이벤트 형태로 값을 전달받을 수 있도록 해준다.
가속도 센서 등록 방법
- SensorManager 인스턴스
SensorManager 인스턴스를 얻는다.
class MainActivity : AppCompatActivity, SensorEventListener {
private val mSensorManager: SensorManager by lazy { getSystemService(Context.SENSOR_SERVICE) as SensorManager }
}
- 가속도 센서를 onResume에 등록
override fun onResume() {
super.onResume()
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL)
}
SensorManager의 객체가 준비되면 Activity가 활성화되어 있을 때에만 센서가 동작을 해야 배터리를 아낄 수 있으며 registerListener()으로 사용할 센서를 등록한다.
- Shake Pay같은 경우는 가속도 센서를 사용해야므로 Sensor.TYPE_ACCELEROMETER 센서를 등록하였다.
- 첫 번째 인자로는 센서를 받을 SensorEventListener이다. 원하는 Activity에서 받기 위하여 SensorEventListener를 등록한 Activity에서 this로 설정한다.
- 두 번째 인자로는 sensorManager의 getDefaultSensor()로 사용할 센서 종류를 지정한다.(가속도 센서 Sensor.TYPE_ACCELEROMETER 지정)
- 세 번째 인자로는 센서값을 받을 빈도 수준을 지정한다. SensorManager 클래스에서 정의한 상수를 사용한다. 여기서는 리소스 낭비를 최소화하기 위해 SENSOR_DELAY_normal을 사용하였다.
- SENSOR_DELAY_FASTEST : 자주 센서 값을 얻는다.
- SENSOR_DELAY_GAME : 게임에 적합한 정도의 센서 값을 얻는다.
- SENSOR_DELAY_NOMAL : 화면 방향이 전환될 때 적합한 정도로 센서 값을 얻는다.
- SENSOR_DELAY_DELAY_UI : 사용자 인터페이스를 표시하기에 적합한 정도로 센서 값을 얻는다.
- SensorEventListener 오버라이드 메서드 설정
- onAccuracyChanged()
- 센서 정밀도가 변경되면 호출
- onSensorChanged()
- 센서 값이 변경되면 호출
override fun onSensorChanged(sensorEvent: SensorEvent?) {}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
안드로이드 센서에서는 x, y, z 3축 좌표계를 사용하며 x축은 수평, y축은 수직, z 축은 화면의 바깥쪽을 향하게 한다. 센서 값을 읽어 올 때는 아래와 같이 읽을 수 있다.
val x: Float = sensorEvent.values[0]
val y: Float = sensorEvent.values[1]
val z: Float = sensorEvent.values[2]
센서 적용
private var lastX: Float = 0f
private var lastY: Float = 0f
private var lastZ: Float = 0f
override fun onSensorChanged(sensorEvent: SensorEvent?) {
sensorEvent?.let {
val x: Float = it.values[0]
val y: Float = it.values[1]
val z: Float = it.values[2]
val curTime = System.currentTimeMillis() // 현재시간
if (curTime - lastUpdate > 100) {
val diffTime: Long = curTime - lastUpdate
lastUpdate = curTime
val speed: Float = abs(x + y + z - lastX - lastY - lastZ) / diffTime * 10000
if (speed > 900) { //지정된 수치이상 흔들림이 있으면 실행
if (viewModel.brandId > 0L) {
showLoading()
viewModel.shakePay() //결제화면 전환
}
}
//갱신
lastX = x
lastY = y
lastZ = z
}
}
'개발 이모저모' 카테고리의 다른 글
시작일부터 종료일 표현해보기 (0) | 2022.12.15 |
---|---|
카카오 주소 및 키워드 api를 활용한 주소 검색 서비스 제작 (0) | 2021.11.16 |
지도에 중복 위경도 마커를 찍어보자 (0) | 2021.11.16 |
SharedPreference를 이용한 최근 검색어 리스트 만들기 (0) | 2021.11.16 |
HTTP 통신 로그 이쁘장하게 찍어보기 (0) | 2021.11.16 |