티스토리 뷰
아이폰의 경우에는 CoreMotion을 사용하면 비교적 쉽게 가져올수있지만
안드로이드는 좀 많이 달라서 천천히 기초적인 것을 먼저 공부해볼까 합니다.
그래서 이번 포스트에서는 앱을 킨 상태에서 걸음수를 측정해볼께요.
(레이아웃은 최소한만 잡고 할께요.)
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/step_detector_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="아직 걷기전" />
<TextView
android:id="@+id/step_count_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="아직 걷기전" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
안드로이드는 걸음수를 측정할때
센서를 거의 반드시 사용해야하기 때문에 권한이 필요합니다.
AndroidManifest.xml 에 반드시 추가해주세요.
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"
tools:remove="android:maxSdkVerSion"/>
<!-- 센서 권한 입니다. -->
MainActivity.kt
그럼 이제 본격적으로 시작해볼까요?
그전에 사전 준비를 위해 몇가지를 미리 정의하고 시작할께요.
0. 필요한 재료들 미리 선언해주세요.
// UI
var dectTextView : TextView? = null // 걸음 센서 작동용
var countTextView : TextView? = null // 총괄 걸음수 작동용
// FUNCTION
var stepDetector : Int = 0 // 걸음 센서 작동 카운터
var stepCounter : Int = 0 // 시작시 총괄 걸음수 카운터
//Sensor
var stepDetectorSensor : Sensor? = null// 걸음 센서 작동 센서
var stepCounterSensor : Sensor? = null// 시작시 총괄 걸음수 센서
private lateinit var sensorManager: SensorManager // 전체 센서 작동
이제 순서대로 필요한 걸 추가해봅시다.
1. 추가해준 권한을 요구하는 함수부터 만들어 줍시다.
fun checkPermission(){
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_DENIED){
// 권한이 거절된 경우
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(arrayOf(
Manifest.permission.ACTIVITY_RECOGNITION),0)
}
}
}
2. 센서를 작동시킬 준비를 해주세요.
fun startSensorWork(){
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
stepDetectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR) // 걸음수
stepCounterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER) // 카운터
}
2-1 Sensor.TYPE_STEP_DETECTOR 랑 Sensor.TYPE_STEP_COUNTER 가 뭔가요?
- 둘다 걸음수를 측정할때 사용되는 센서입니다. 저는 둘다 사용해 볼께요.
- 상황에 따라 더 적합한걸 사용하시면 됩니다.
- 둘 다 사용자가 걸었다고 인지하면 작동합니다.
- TYPE_STEP_DETECTOR : 작동시 1.0의값을 줍니다. COUNTER에 비해 속도가 빠릅니다.
- TYPE_STEP_COUNTER : 사용자가 걸을때 휴대폰이 켜진 상태에서 걸은 총 누적 걸음수를 돌려줍니다.
- COUNTER의 경우 휴대폰을 재시작하시면 0 부터 다시 시작합니다.
2-2 센서 이벤트를 감지해주는 부분을 만들어줍니다.
- 아래처럼 SensorEventListener 먼저 추가해주시고
class MainActivity : AppCompatActivity(),SensorEventListener {
- 센서가 작동시 작동시킬 함수를 같이 만들어주세요.
// 센서에서 값을 받아오는 속도 조절
override fun onStart() {
super.onStart()
if(stepDetectorSensor != null && stepCounterSensor != null){
sensorManager.registerListener(this,stepDetectorSensor,SensorManager.SENSOR_DELAY_FASTEST)
sensorManager.registerListener(this,stepCounterSensor,SensorManager.SENSOR_DELAY_FASTEST)
}
}
//Dect 용
fun dectMotion(){
stepDetector += 1
dectTextView?.text = "감지 횟수 : $stepDetector"
}
//Counter 용
fun countMotion(nowValue : Int){
val getStep = nowValue - this.stepCounter
countTextView?.text = "걸음수 : $getStep"
}
// 센서 감지 및
override fun onSensorChanged(event: SensorEvent?) {
if(event?.sensor?.type == Sensor.TYPE_STEP_DETECTOR){
if(event.values.first() == 1.0f){ // 걸었다는 신호
this.dectMotion() // 1씩증가
}
}
if(event?.sensor?.type == Sensor.TYPE_STEP_COUNTER){
if (this.stepCounter <= 0){ // 맨처음 시작인 경우
this.stepCounter = event.values.first().toInt()
}else{ // 현재 누적값에서 지금 누적값을 빼서 구하는 방법
this.countMotion(event.values.first().toInt())
}
}
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
// TODO("Not yet implemented")
}
- TYPE_STEP_DETECTOR는 1씩 증가 / TYPE_STEP_COUNTER는 총걸음수의 차이량을 표시하게 만들어 둘께요.
3. onCreate 에 여태까지 만들걸 넣고 실행해주세요.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
dectTextView = findViewById<TextView>(R.id.step_detector_tv)
countTextView = findViewById<TextView>(R.id.step_count_tv)
checkPermission()
startSensorWork()
}
4. 실행하고 권한을 수락해주세요.
5. 실제로 열심히 걷거나 흔드시면(?) 숫자가 바뀌는걸 알 수 있습니다.
- 자세히 보시면 둘의 숫자 차이가 있다는 걸 알 수 있습니다.
- 걸음수의 경우 느리긴하지만 Counter 가 더 정확하다고 합니다.
* MainActivity.kt 전체 코드
class MainActivity : AppCompatActivity(),SensorEventListener {
// UI
var dectTextView : TextView? = null // 걸음 센서 작동용
var countTextView : TextView? = null // 총괄 걸음수 작동용
// FUNCTION
var stepDetector : Int = 0 // 걸음 센서 작동 카운터
var stepCounter : Int = 0 // 시작시 총괄 걸음수 카운터
//Sensor
var stepDetectorSensor : Sensor? = null// 걸음 센서 작동 센서
var stepCounterSensor : Sensor? = null// 시작시 총괄 걸음수 센서
private lateinit var sensorManager: SensorManager // 전체 센서 작동
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
dectTextView = findViewById<TextView>(R.id.step_detector_tv)
countTextView = findViewById<TextView>(R.id.step_count_tv)
checkPermission()
startSensorWork()
}
override fun onStart() {
super.onStart()
if(stepDetectorSensor != null && stepCounterSensor != null){
sensorManager.registerListener(this,stepDetectorSensor,SensorManager.SENSOR_DELAY_FASTEST)
sensorManager.registerListener(this,stepCounterSensor,SensorManager.SENSOR_DELAY_FASTEST)
}
}
fun checkPermission(){
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_DENIED){
// 권한이 거절된 경우
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(arrayOf(
Manifest.permission.ACTIVITY_RECOGNITION),0)
}
}
}
fun startSensorWork(){
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
stepDetectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR) // 걸음수
stepCounterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER) // 카운터
}
//Dect 용
fun dectMotion(){
stepDetector += 1
dectTextView?.text = "감지 횟수 : $stepDetector"
}
//Counter 용
fun countMotion(nowValue : Int){
val getStep = nowValue - this.stepCounter
countTextView?.text = "걸음수 : $getStep"
}
// 센서 감지 및
override fun onSensorChanged(event: SensorEvent?) {
if(event?.sensor?.type == Sensor.TYPE_STEP_DETECTOR){
if(event.values.first() == 1.0f){ // 걸었다는 신호
this.dectMotion() // 1씩증가
}
}
if(event?.sensor?.type == Sensor.TYPE_STEP_COUNTER){
if (this.stepCounter <= 0){ // 맨처음 시작인 경우
this.stepCounter = event.values.first().toInt()
}else{ // 현재 누적값에서 지금 누적값을 빼서 구하는 방법
this.countMotion(event.values.first().toInt())
}
}
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
// TODO("Not yet implemented")
}
}
여기까지 드디어 걸음수 측정의 기초를 다루어 봤는데요
이 원리를 응용하면 만보기앱도 쉽게 만들 수 있겠죠?
도움이 되시길 바라며
오늘도 파이팅입니다~
'Android 연습 > Kotlin 익숙해지기' 카테고리의 다른 글
Kotlin onBackPressed deprecated 발생 (0) | 2023.03.02 |
---|---|
Kotlin Kotpref 이용해서 간단하게 값 저장하기 (0) | 2023.02.28 |
Kotlin Service 기기 재시동후에 자동 실행시키기 (0) | 2023.02.21 |
Kotlin 연습 Lottie / Gif로 움직이는 사진 넣기 (0) | 2023.01.22 |
Kotlin 연습 SharedPreference (with. 앱 테마 바꾸기) (0) | 2023.01.10 |