๋ชฉ์ฐจ
9/2
์ ๋ฌด ๋ด์ฉ
- ๊ณ ๊ฐ์ฌ ์ธก์ ์ถ๊ฐ ๊ฐ๋ฐ ๋ด์ฉ ๊ฒํ ๋ฐ ์๋ฃ ์ ๋ฆฌ
- ๋์์ด๋๋ถ๊ป ์ถ๊ฐ ๊ฐ๋ฐ ๋ด์ฉ ์๋ฃ ์ ๋ฌ ํ ์ถ๊ฐ๋ ํ๋ฉด ๋์์ธ ์์ฒญ
- ์ฌ๋ฐ์ ๋ชจ๋ํฐ๋ง ์ฝ๋ ์ถ๊ฐ
- ์ธก์ ๋๋ ์ฌ๋ฐ์๋ฅผ ํ๋ฉด์ ๋ณด์ด๊ฒ ํ๊ณ
- ์ค์ ๋ ์ฃผ๊ธฐ์ ๋ฐ๋ผ ํ๋ฉด์ ๋ณด์ด๋ ์ฌ๋ฐ์ ๋ฐ์ดํฐ ์ ๋ฐ์ดํธํ๋๋ก ๊ตฌํ
- ํ์ฌ๋ ๋๋ฏธ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค์ด์ ๋ก์ง ํ์ธ
- ์ฌ๋ฐ์ ์
๋ ฅ ํ๋ฉด ์ถ๊ฐ
- numpicker ๋ฅผ ํตํด ์ฌ๋ฐ์ ์์น ์ ๋ ฅ
- ์ด ๋ ์์ ๋จ์๋ 10์ผ๋ก ์ค์
- *displayedValues* ๋ฅผ ํตํด numpicker์์ ๋ณด์ฌ์ค ์ ์กฐ์ ๊ฐ๋ฅ
- minValue์ maxValue๋ ์ธ๋ฑ์ค ๊ฐ์ ๋ํ๋
- ์ฌ๋ฐ์ ์ ๋ ฅ ํ ์ฌ๋ฐ์ ๋ก์ปฌ ์ ์ฅ ์ถ๊ฐ
- PreferenceUtil.setDangerHeart(this@HeartRateActivity,displayedValues[binding.dangerHeart.value])
- ์ด์ ์ฌ๋ฐ์ ๊ฐ์ง ์ฝ๋ ์ถ๊ฐ
- ์ฌ๋ฐ์ ์ธก์ ์ ์ด์ ์ฌ๋ฐ์๋ฅผ ๊ฐ์งํ๋ ์กฐ๊ฑด๋ฌธ ์ถ๊ฐ
9/3
- ๊ธฐ์กด ํํ๋ฉด ๋ฌธ์ ํด๊ฒฐ
- ๊ธฐ์กด : ๋ฐ์ดํฐ๊ฐ ์ ์ก ์ค์ด๊ฑฐ๋ ์ค์ง์ํ์ธ ์ํฉ์ ์ฆ๊ฐ์ ์ผ๋ก ๋ฐ์ํ์ง ๋ชปํจ
- ํ์ฌ : ๋ฐ์ดํฐ๊ฐ ์ ์ก ์ค์ด๊ฑฐ๋ ์ค์ง์ํ์ธ ์ํฉ์ ์ฆ๊ฐ์ ์ผ๋ก ๋ฐ์
- StateFlow ๋ณ์ ์ด์ฉ
- ์ฌ๋ฐ์ ๋ชจ๋ํฐ๋ง์ ์ํด ์ฌ์ฉํ๋ broadcastreceiver ๋ฐฉ์ ๋์ livedata๋ฅผ ์ฌ์ฉ ๊ฐ๋ฅํ์
- ๋ฐ๋ผ์ ์๋น์ค ๋ด์ livedata๋ณ์๋ฅผ ์์ฑํ๊ณ , ๋ฐ์ดํฐ ์ ์ฅ ํ
- ์กํฐ๋นํฐ์ ์๋น์ค๋ฅผ ๋ฐ์ธ๋ฉํด์ฃผ๊ณ
- ์กํฐ๋นํฐ์์ ์๋น์ค์ livedata ๋ณ์๋ฅผ ๊ด์ฐฐํ์ฌ UI ์ ๋ฐ์ดํธ ํ๋๋ก ์ฝ๋๋ฅผ ์์ ํ์๋ค.
- ์ด์ ์ฌ๋ฐ์ ์ข ๋ฅ (warn, danger) ์ ํ๋จํ ์ ์๋๋ก ์๋น์ค์์ WARN, DANGER ๋ฌธ์์ด์ ๋๊ฒจ์ค ํ ์กํฐ๋นํฐ์์ ๊ฐ ์ข ๋ฅ์ ๋ฐ๋ผ ํ ์คํธ ๋ฉ์์ง ๋์์ค
- ์ต์ข : livedata๋ก์ง → flow๋ก ๋ณ๊ฒฝ
์ถ๊ฐ๋ ์๊ตฌ์ฌํญ ์ ๋ฆฌ
- ์ฌ๋ฐ์ ํ๋ฉด์ ํ์ํ๊ธฐ
- IP ์ฃผ์ ์
๋ ฅ ํ ์ฌ๋ฐ ๋ฒ์๋ฅผ ์
๋ ฅํด์ ์์ฒญํ๋ ๋ก์ง ์ถ๊ฐ
- ์ํ, ๊ฒฝ๊ณ ์ ์ ๊ธฐ์ค๊ฐ๋ค ์
๋ ฅ ํ ์๋ฒ๋ก ์ ๋ฌ
- ์ํ, ๊ฒฝ๊ณ ๋ก ํ๋จํ ์ฌ๋ฐ์ ์ ๋ ฅ ํ์
- ์ ๋ ฅ ํ ์๋ฒ๋ก ์ ๋ฌ
- ์ํ, ๊ฒฝ๊ณ ์ ์ ๊ธฐ์ค๊ฐ๋ค ์
๋ ฅ ํ ์๋ฒ๋ก ์ ๋ฌ
- ๋ฐ์ดํฐ ์ธก์ ๋์ค ์ค์ ํ ์ฌ๋ฐ์๋ฅผ ๋์ด๊ฐ๋ ์์น๊ฐ ๊ธฐ๋ก๋๋ฉด ์์น + ์น์์ ์๋ ๊ธฐ๋ฅ ๋์
- ๊ธฐ์ค ์ฌ๋ฐ์๋ db์์ ์กฐํํ์ฌ ์ ๋ ฅ๋ ๊ธฐ์ค ์ฌ๋ฐ์๋ฅผ ๊ฐ์ ธ์์ ํ๋จ
๊ทผ๋ก์ ์ถ๋ฝ ๋ฐ ์ฐ๋ฌ์ง ๊ฐ์ง
- ๊ทผ๋ก์ ์ถ๋ฝ ๋ฐ ์ฐ๋ฌ์ง ๊ฐ์ง ๋ก์ง ์ถ๊ฐ
- ๋ฐ์ ์ ์์น์ ์ฑ์์ ์๋ฆผ ๊ธฐ๋ฅ ๋์
์ด์ ์ฌ๋ฐ์ ๊ฐ์ง
- ์ด์ ์ฌ๋ฐ์ ๊ฐ์ง๋ฅผ ์ํ ์ฌ๋ฐ์ ์ ๋ ฅ ๋ ์ด์์ ์ถ๊ฐ
- ์ ๋ ฅ๋ ์ฌ๋ฐ์ (์ ์, ์ํ, ๊ฒฝ๊ณ )๋ฅผ ๋ก์ปฌ db์ ์ ์ฅํ๋ ๋ก์ง ์ถ๊ฐ
binding.btnComplete.setOnClickListener {
CoroutineScope(Dispatchers.IO).launch {
PreferenceUtil.setDangerHeart(this@HeartRateActivity,binding.dangerHeart.value.toString())
PreferenceUtil.setWarnHeart(this@HeartRateActivity,binding.warnNumber.value.toString())
PreferenceUtil.setNormalHeart(this@HeartRateActivity,binding.normalHeart.value.toString())
๋ฐ๋ก number picker์ value๋ฅผ ์ ์ฅํ ๋์๋ ์๋์ ๊ฐ์ด ๋ด๊ฐ ์ํ๋ ์ฌ๋ฐ์ ๊ฐ์ด ์๋๋ผ ์ธ๋ฑ์ค๊ฐ ์ ์ฅ๋๋ค.
๊ทธ๋ฌ๋ ์ฌ๋ฐ์ ๊ฐ์ด ์ ์ฅ๋ ๋ฆฌ์คํธ์ ์ธ๋ฑ์ค๋ก ์ ๊ทผํ ํ ์ป์ ๋ฐ์ดํฐ๋ฅผ ๋๊ฒจ์ค ๊ฒฐ๊ณผ ์๋์ ๊ฐ์ด ์ ์ ์ฅ๋์๋ค.
binding.btnComplete.setOnClickListener {
CoroutineScope(Dispatchers.IO).launch {
// ์ฌ๋ฐ์ ์ ์ฅ ๋ก์ง
PreferenceUtil.setDangerHeart(this@HeartRateActivity,displayedValues[binding.dangerHeart.value])
PreferenceUtil.setNormalHeart(this@HeartRateActivity,displayedValues[binding.normalHeart.value])
PreferenceUtil.setWarnHeart(this@HeartRateActivity,displayedValues[binding.warnNumber.value])
}
}
Sensor.TYPE_HEART_RATE ->{
val heartRate = event.values[0].toInt()
heartrateData.add(heartRate)
// todo : ์ฌ๋ฐ์ ์ด์ ๋ก์ง ์ถ๊ฐ
val normalHeart = PreferenceUtil.getNormalHeart(this)
val warnHeart = PreferenceUtil.getWarnHeart(this)
val dangerHeart = PreferenceUtil.getDangerHeart(this)
Log.d("normalheart", normalHeart!!.toInt().toString())
if (heartRate ==0) {
Log.d("์๋น
"," ์ฌ๋ฐ์๊ฐ 0 : ์ธก์ ์ค๋ฅ /์ํ")
}
if (heartRate < normalHeart.toInt()) {
Log.d("์๋น
"," ์ฌ๋ฐ์ < ์ ์")
}
if(heartRate >= dangerHeart!!.toInt()) {
Log.d("์๋น
"," ์ฌ๋ฐ์ >= ์ ์")
}
if(heartRate >= warnHeart!!.toInt() && heartRate < dangerHeart.toInt()) {
Log.d("์๋น
"," ๊ฒฝ๊ณ <= ์ฌ๋ฐ์ < ์ํ ")
}
if (heartRate >= normalHeart.toInt() && heartRate < warnHeart.toInt()) {
Log.d("์๋น
"," ์ ์ <= ์ฌ๋ฐ์ < ๊ฒฝ๊ณ ")
}
else {
Log.d("์ ์์ด์ฉ","์ ์์ ์ผ๋ก ์ธก์ ์ค")
}
}
else if๋ก ์ฝ๋ ์์ฑ ์ ์กฐ๊ฑด๋ฌธ ์์ ๋ก๊ทธ ์คํ๋์ง ์์ if๋ก ๋ฐ๊ฟ์ฃผ๋๊น ๋ก๊ทธ ์ฐํ
9/3
- ๊ธฐ์กด ํํ๋ฉด ๋ฌธ์ ํด๊ฒฐ
- ๊ธฐ์กด : ๋ฐ์ดํฐ๊ฐ ์ ์ก ์ค์ด๊ฑฐ๋ ์ค์ง์ํ์ธ ์ํฉ์ ์ฆ๊ฐ์ ์ผ๋ก ๋ฐ์ํ์ง ๋ชปํจ
- ํ์ฌ : ๋ฐ์ดํฐ๊ฐ ์ ์ก ์ค์ด๊ฑฐ๋ ์ค์ง์ํ์ธ ์ํฉ์ ์ฆ๊ฐ์ ์ผ๋ก ๋ฐ์
- StateFlow ๋ณ์ ์ด์ฉ
- ์ฌ๋ฐ์ ๋ชจ๋ํฐ๋ง์ ์ํด ์ฌ์ฉํ๋ broadcastreceiver ๋ฐฉ์ ๋์ livedata๋ฅผ ์ฌ์ฉ ๊ฐ๋ฅํ์
- ๋ฐ๋ผ์ ์๋น์ค ๋ด์ livedata๋ณ์๋ฅผ ์์ฑํ๊ณ , ๋ฐ์ดํฐ ์ ์ฅ ํ
- ์กํฐ๋นํฐ์ ์๋น์ค๋ฅผ ๋ฐ์ธ๋ฉํด์ฃผ๊ณ
- ์กํฐ๋นํฐ์์ ์๋น์ค์ livedata ๋ณ์๋ฅผ ๊ด์ฐฐํ์ฌ UI ์ ๋ฐ์ดํธ ํ๋๋ก ์ฝ๋๋ฅผ ์์ ํ์๋ค.
- ์ด์ ์ฌ๋ฐ์ ์ข ๋ฅ (warn, danger) ์ ํ๋จํ ์ ์๋๋ก ์๋น์ค์์ WARN, DANGER ๋ฌธ์์ด์ ๋๊ฒจ์ค ํ ์กํฐ๋นํฐ์์ ๊ฐ ์ข ๋ฅ์ ๋ฐ๋ผ ํ ์คํธ ๋ฉ์์ง ๋์์ค
- ์ต์ข : livedata๋ก์ง → flow๋ก ๋ณ๊ฒฝ
9/4
- ์ฌ๋ฐ์ ์
๋ ฅ
- ํ๋ฉด ์ ์ฉ
- ์ฌ๋ฐ์ ์
๋ ฅ ์๊ตฌ ์ฌํญ ๊ตฌํ
- ์คํฌ๋กค ์ ๊ฒฝ๊ณ ์ฌ๋ฐ์, ์ ์ ์ฌ๋ฐ์, ์ํ ์ฌ๋ฐ์๋ก ์ ํ
- ์ฌ๋ฐ์ ํ์ ์ ํ ์ ํ์ฌ ์ค์ ๋ ์ฌ๋ฐ์ ์์น๋ฅผ ํด๋์ค ๋ด๋ถ์ ์ ์ฅ
- ์ฌ๋ฐ์ ์์น๊ฐ ๋ชจ๋ ํด๋์ค ๋ด ๋ณ์์ ์ ์ฅ๋์์ ๊ฒฝ์ฐ ๋ค์ ์ฌ๋ฐ์ ํ์ ๋ณ๊ฒฝ ์ ์ ์ฅ๋ ์์น ๋ณด์ด๊ธฐ
- ์๋ฃ ๋ฒํผ ํด๋ฆญ ์ ๋ก์ปฌ db์ ํด๋น ๊ฐ ์ ์ฅ
- ์ค์ ๊ธฐ๊ธฐ์์ ์ฌ๋ฐ์ ๋ชจ๋ํฐ๋ง ์ฝ๋ ํ์ธ ๋ฐ apk ํ์ผ ์ ๋ฌ
- ์๋ฆผ ๋ฉ์์ง ์์ (์ฌ๋ฐ์ ์ด์ ๊ฐ์ง, ๊ทผ๋ก์ ์ด์ ๊ฐ์ง)
- ์ค์ ๊ธฐ๊ธฐ์์ ์ด์ ์ฌ๋ฐ์ ์๋ฆผ ํ์ธ
- ์ค์ ๊ธฐ๊ธฐ์์ ์ถ๋ฝ ๊ฐ์ง ํ์ธ
- ์ถ๊ฐ : ๊ทผ๋ก์์ ์ถ๋ฝ์ ๊ฐ์งํ๊ธฐ์ ํจ์จ์ ์ธ์ง ํ์ธ ํ์
- ์์น๋ฅผ ์ํ ์ข์ฐ๋ก ํ๋ค๋ฉฐ ๊ฐ์ง ํ์ธ
- ๋์ ์์ ์์ธ
- ํ๋ฉด์ UI๊ฐ ๋ณด์ด์ง ์์ ๋์๋ ๋ณํ๋ ๋ฐ์ดํฐ flow ์์ง์ ์ค๋จํ์ (์ฌ๋ฐ์ ๋ชจ๋ํฐ๋ง, ์ด์ ์ฌ๋ฐ์, ์ถ๋ฝ ๊ฐ์ง)
// ๊ธฐ์กด
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val sensorBinder = service as SensorForegroundService.SensorBinder
sensorService = sensorBinder.getService()
sensorBound = true
lifecycleScope.launch {
sensorService.heartRateStateFlow.collect { heartRate ->
binding.heartRateText.text = heartRate.toString()
}
}
lifecycleScope.launch {
sensorService.fallAlertStateFlow.collect {
if (it) showDialog("๊ทผ๋ก์ ์ด์ ๊ฐ์ง")
}
}
lifecycleScope.launch {
sensorService.heartRateAlertStateFlow.collect { heartAlert ->
when (heartAlert) {
"WARN", "DANGER" -> showDialog("์ฌ๋ฐ์ ์ด์ ๊ฐ์ง")
}
}
}
lifecycleScope.launch{
sensorService.heartRateRunning.collect {
if (!it) {
binding.heartRateText.text = "๋ฐ์ดํฐ ์ ์ก ์ค์ง"
binding.locationText.text = "๋ฐ์ดํฐ ์ ์ก ์ค์ง"
} else {
binding.locationText.text = "๋ฐ์ดํฐ ์ ์ก ์ค"
}
}
}
}
lifecycleScope.launch ๋ด๋ถ์์ ๋ฐ๋ก flow ๋ฐ์ดํฐ ์ฌ์ฉํ๋ฉด ์๋จ!!
๋ฐฑ๊ทธ๋ผ์ด๋์ ์ฑ์ด ์์นํด๋ flow์์ ์์ง์ ์ค๋จํ์ง ์๋๋ค.
์ด ๋ฌธ์ ํด๊ฒฐ์ ์ํด์๋ ์กํฐ๋นํฐ๊ฐ ํ๋ฉด์ ๋ณด์ผ ๋ ํธ์ถ๋๋ onStart์์ ์์ง์ ์์ํ๊ณ ํ๋ฉด์์ ์ฌ๋ผ์ง ๋ ํธ์ถ๋๋ onStop์์ ์์ง์ ์ค๋จํด์ผํ๋ค.
์ด ์ผ์ ๋์ ํด์ฃผ๋ ๊ฒ์ด repeatOnLifecycler!!!
//์์
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED){
launch {
sensorService.heartRateStateFlow.collect { heartRate ->
/*
์
๋ฐ์ดํธ๋๋ ์๊ฐ ํ์ธํ๊ธฐ
*/
Log.d("์ฌ๋ฐ์ ์
๋ ", heartRate.toString())
binding.heartRateText.text = heartRate.toString()
}
}
launch {
sensorService.fallAlertStateFlow.collect {
if (it) showDialog("๊ทผ๋ก์ ์ด์ ๊ฐ์ง")
}
}
launch {
sensorService.heartRateAlertStateFlow.collect { heartAlert ->
when (heartAlert) {
"WARN", "DANGER" -> showDialog("์ฌ๋ฐ์ ์ด์ ๊ฐ์ง")
}
}
}
launch {
sensorService.heartRateRunning.collect {
if (!it) {
binding.heartRateText.text = "๋ฐ์ดํฐ ์ ์ก ์ค์ง"
binding.locationText.text = "๋ฐ์ดํฐ ์ ์ก ์ค์ง"
} else {
binding.locationText.text = "๋ฐ์ดํฐ ์ ์ก ์ค"
}
}
}
}
}
flow๋ก ๋ฐ์ดํฐ๋ฅผ ์์งํ ๋ ์ผ๋ง๋ ์ค๋ ์์ง๋์ด์ผํ๋๊ฐ?
์ฌ์ค ํ๋ฉด์ UI๊ฐ ํ์๋์ง ์์ ๋๋ flow์์ ์์ง์ ์ค๋จํด์ผํ๋ค.
1. .asLiveData() ๋ฅผ ํตํด flow๋ฅผ LiveData๋ก ๋ณํํด์ UI๊ฐ ํ๋ฉด์ ํ์๋๋๋์์๋ง ์์ดํ ์ ๊ด์ฐฐ
2. repeatOnLifeCycle ์ ํตํด ์๋ช ์ฃผ๊ธฐ๋ฅผ ์ธ์ํ์ฌ ์๋ช ์ฃผ๊ธฐ๊ฐ ํด๋นํ๋ ์ํ์ ๋๋ฌํ๋ฉด ๋ธ๋ก์ ์ ๋ฌํ ์๋ก์ด ์ฝ๋ฃจํด์ ์๋์ผ๋ก ์์ํ๊ณ , ํด๋น ์๋ช ์ฃผ๊ธฐ ์๋๋ก ๋จ์ด์ง๋ฉด ์ทจ์ํ๋ค.
3. ์ฌ๋ฌ ๊ฐ์ flow๋ฅผ ์์งํด์ผํ๋ ๊ฒฝ์ฐ(์ฌ๋ฐ์ , ์ด์ ์ฌ๋ฐ์ ์ฌ๋ถ, ์ถ๋ฝ ์ฌ๋ถ ๋ฑ) repeatOnLifeCycle ๋ธ๋ก์์ launch๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ์ฝ๋ฃจํด ์์ฑ ๊ฐ๋ฅ!!
'๐ค2024 ์๋๋ก์ด๋ > โ๏ธ ํ๊ณ ์ธํด ๊ฐ๋ฐ ํ๋ก์ ํธ ๊ธฐ๋ก' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
โบ๏ธ ์ธํด ๊ฐ๋ฐ์ผ์ง ๋ชจ์ (1) | 2024.12.17 |
---|---|
11์ฃผ์ฐจ ๊ฐ๋ฐ์ผ์ง (0) | 2024.12.17 |
9์ฃผ์ฐจ ๊ฐ๋ฐ์ผ์ง (0) | 2024.12.17 |
8์ฃผ์ฐจ ๊ฐ๋ฐ์ผ์ง (0) | 2024.12.17 |
7์ฃผ์ฐจ ๊ฐ๋ฐ์ผ์ง (0) | 2024.12.17 |