Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor : Single feature 리팩토링 수행 #165

Closed
wants to merge 10 commits into from
10 changes: 1 addition & 9 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
android:roundIcon="@mipmap/ic_partyrun_round"
android:supportsRtl="true"
android:theme="@style/Theme.PartyRunApplication"
tools:replace="android:allowBackup"
tools:targetApi="31">
<meta-data
android:name="com.google.android.geo.API_KEY"
Expand All @@ -43,15 +44,6 @@
android:theme="@style/Theme.PartyRunApplication"
android:launchMode="singleTop">
</activity>
<service
android:name=".feature.running.service.BaseRunningService"
android:foregroundServiceType="location" />
<service
android:name=".feature.running.service.BattleRunningService"
android:foregroundServiceType="location" />
<service
android:name=".feature.running.service.SingleRunningService"
android:foregroundServiceType="location" />
</application>

</manifest>
20 changes: 19 additions & 1 deletion feature/running/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
<application
android:usesCleartextTraffic="false">
<service
android:name=".service.BaseRunningService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="location" />
<service
android:name=".service.BattleRunningService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="location" />
<service
android:name=".service.SingleRunningService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="location" />
</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,17 @@ class SingleRunningService : BaseRunningService() {
private fun setLocationCallback() {
locationCallback = object : LocationCallback() {
override fun onLocationResult(result: LocationResult) {
// onLocationResult의 반환 값이 이전 위치일수도 있는 첫 번째 값은 무시
if (isFirstLocationUpdate) {
isFirstLocationUpdate = false // 플래그 업데이트
return
}
if (shouldSkipLocationUpdate()) return
processLocationResult(result.lastLocation)
}
}
}

// onLocationResult의 반환 값이 이전 위치일수도 있는 첫 번째 값은 무시
private fun shouldSkipLocationUpdate(): Boolean {
return isFirstLocationUpdate.also { isFirstLocationUpdate = false }
}

private fun processLocationResult(location: Location?) {
location?.let {
if (handleUserPause(it)) return@let
Expand All @@ -118,30 +119,43 @@ class SingleRunningService : BaseRunningService() {
}
}

private fun handleAutomaticPause(it: Location): Boolean {
if (lastSensorVelocity <= THRESHOLD) {
belowThresholdCount++
if (runningServiceState == RunningServiceState.PAUSED) {
lastLocation = it // 일시정지 상태일 때는 마지막 위치만 업데이트
return true
private fun handleUserPause(location: Location): Boolean {
if (isUserPaused) { // 사용자가 직접 일시정지 한 경우, 위치 업데이트만 수행하고 리턴
lastLocation = location
return true
}
return false
}

private fun handleAutomaticPause(currentLocation: Location): Boolean {
return when {
isBelowThreshold() -> {
handleBelowThresholdSituation(currentLocation)
true
}
if (shouldPauseService()) {
pauseRunningService()

runningServiceState == RunningServiceState.PAUSED -> {
resumeRunningService()
false
}
return true

else -> false
}
}

private fun isBelowThreshold() = lastSensorVelocity <= THRESHOLD

private fun handleBelowThresholdSituation(currentLocation: Location) {
belowThresholdCount++

if (runningServiceState == RunningServiceState.PAUSED) {
resumeRunningService()
lastLocation = currentLocation
return
}
return false
}

private fun handleUserPause(location: Location): Boolean {
if (isUserPaused) { // 사용자가 직접 일시정지 한 경우, 위치 업데이트만 수행하고 리턴
lastLocation = location
return true
if (shouldPauseService()) {
pauseRunningService()
}
return false
}

override fun addGpsDataToRecordData(location: Location) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,36 +143,22 @@ private fun StartRunningService(
val context = LocalContext.current
val receiver = remember { createBroadcastReceiver(singleContentViewModel) }

when (singleContentUiState.runningServiceState) {
RunningServiceState.STARTED -> ControlRunningService(
singleContentViewModel,
Constants.ACTION_START_RUNNING,
receiver,
context
)

RunningServiceState.PAUSED -> ControlRunningService(
singleContentViewModel,
Constants.ACTION_PAUSE_RUNNING,
receiver,
context,
isUserPaused = singleContentUiState.isUserPaused
)

RunningServiceState.RESUMED -> ControlRunningService(
singleContentViewModel,
Constants.ACTION_RESUME_RUNNING,
receiver,
context
)

RunningServiceState.STOPPED -> ControlRunningService(
singleContentViewModel,
Constants.ACTION_STOP_RUNNING,
receiver,
context
)
val action = when (singleContentUiState.runningServiceState) {
RunningServiceState.STARTED -> Constants.ACTION_START_RUNNING
RunningServiceState.PAUSED -> Constants.ACTION_PAUSE_RUNNING
RunningServiceState.RESUMED -> Constants.ACTION_RESUME_RUNNING
RunningServiceState.STOPPED -> Constants.ACTION_STOP_RUNNING
}

ControlRunningService(
singleContentViewModel = singleContentViewModel,
action = action,
receiver = receiver,
context = context,
isUserPaused = if (singleContentUiState.runningServiceState == RunningServiceState.PAUSED) {
singleContentUiState.isUserPaused
} else false
)
}

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,24 @@ import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject

@HiltViewModel
class SingleViewModel @Inject constructor(
class SingleViewModel @Inject constructor() : ViewModel() {

companion object {
const val INITIAL_DISTANCE = 5000 // 'm' 단위
const val INITIAL_TIME = 900 // '초' 단위, 900초 = 15분
const val DISTANCE_INCREMENT = 250
const val TIME_INCREMENT = 300
const val SECONDS_IN_HOUR = 3600
const val SECONDS_IN_MINUTE = 60
}

) : ViewModel() {
private val _singleUiState = MutableStateFlow<SingleUiState>(SingleUiState.Success)
val singleUiState: StateFlow<SingleUiState> = _singleUiState

private val _targetDistance = MutableStateFlow(5000) // 'm' 단위
private val _targetDistance = MutableStateFlow(INITIAL_DISTANCE)
val targetDistance: StateFlow<Int> = _targetDistance

private val _targetTime = MutableStateFlow(900) // '초' 단위, 900초 = 15분
private val _targetTime = MutableStateFlow(INITIAL_TIME)
val targetTime: StateFlow<Int> = _targetTime

private val _snackbarMessage = MutableStateFlow("")
Expand All @@ -27,29 +35,29 @@ class SingleViewModel @Inject constructor(
}

fun incrementTargetDistance() {
_targetDistance.value += 250
_targetDistance.value += DISTANCE_INCREMENT
}

fun decrementTargetDistance() {
if (_targetDistance.value > 250) {
_targetDistance.value -= 250
if (_targetDistance.value > DISTANCE_INCREMENT) {
_targetDistance.value -= DISTANCE_INCREMENT
}
}

fun incrementTargetTime() {
_targetTime.value += 300
_targetTime.value += TIME_INCREMENT
}

fun decrementTargetTime() {
if (_targetTime.value > 300) {
_targetTime.value -= 300
if (_targetTime.value > TIME_INCREMENT) {
_targetTime.value -= TIME_INCREMENT
}
}

fun getFormattedTargetTime(): String {
val hours = _targetTime.value / 3600
val remainingTime = _targetTime.value % 3600
val minutes = remainingTime / 60
val hours = _targetTime.value / SECONDS_IN_HOUR
val remainingTime = _targetTime.value % SECONDS_IN_HOUR
val minutes = remainingTime / SECONDS_IN_MINUTE
return String.format("%02d:%02d", hours, minutes)
}

Expand Down