Skip to content

Commit 4aea853

Browse files
bngshyonghanJu
andcommitted
✨ RunningWorker 구현
Co-authored-by: yonghanJu <[email protected]>
1 parent 7aa01fd commit 4aea853

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.whyranoid.presentation.running
2+
3+
import android.content.Context
4+
import androidx.hilt.work.HiltWorker
5+
import androidx.work.CoroutineWorker
6+
import androidx.work.WorkerParameters
7+
import com.google.android.gms.location.FusedLocationProviderClient
8+
import com.google.android.gms.location.LocationServices
9+
import com.google.android.gms.location.Priority
10+
import com.google.android.gms.tasks.CancellationToken
11+
import com.google.android.gms.tasks.CancellationTokenSource
12+
import com.google.android.gms.tasks.OnTokenCanceledListener
13+
import dagger.assisted.Assisted
14+
import dagger.assisted.AssistedInject
15+
import kotlinx.coroutines.delay
16+
import kotlin.coroutines.resume
17+
import kotlin.coroutines.suspendCoroutine
18+
19+
@HiltWorker
20+
class RunningWorker @AssistedInject constructor(
21+
@Assisted context: Context,
22+
@Assisted params: WorkerParameters,
23+
private val runningRepository: RunningRepository
24+
) : CoroutineWorker(context, params) {
25+
26+
private val fusedLocationClient: FusedLocationProviderClient by lazy {
27+
LocationServices.getFusedLocationProviderClient(context)
28+
}
29+
30+
override suspend fun doWork(): Result {
31+
startTracking()
32+
33+
while ((runningRepository.runningState.value is RunningState.NotRunning).not()) {
34+
delay(1000)
35+
when (runningRepository.runningState.value) {
36+
is RunningState.NotRunning -> break
37+
is RunningState.Paused -> continue
38+
is RunningState.Running -> trackRunningData()
39+
}
40+
}
41+
return Result.success()
42+
}
43+
44+
private suspend fun startTracking(): Boolean {
45+
// TODO: getCurrentLocation을 requestLocationUpdates로 변경
46+
return suspendCoroutine { continuation ->
47+
try {
48+
fusedLocationClient.getCurrentLocation(
49+
Priority.PRIORITY_HIGH_ACCURACY,
50+
object : CancellationToken() {
51+
override fun onCanceledRequested(p0: OnTokenCanceledListener): CancellationToken {
52+
return CancellationTokenSource().token
53+
}
54+
55+
override fun isCancellationRequested(): Boolean {
56+
return false
57+
}
58+
}
59+
).addOnSuccessListener { location ->
60+
runningRepository.startRunning(
61+
RunningPosition(
62+
location.latitude,
63+
location.longitude
64+
)
65+
)
66+
continuation.resume(true)
67+
}.addOnFailureListener {
68+
runningRepository.pauseRunning()
69+
continuation.resume(false)
70+
}
71+
} catch (exception: SecurityException) {
72+
runningRepository.pauseRunning()
73+
continuation.resume(false)
74+
} catch (e: Exception) {
75+
continuation.resume(false)
76+
}
77+
}
78+
}
79+
80+
private fun trackRunningData() {
81+
try {
82+
fusedLocationClient.getCurrentLocation(
83+
Priority.PRIORITY_HIGH_ACCURACY,
84+
object : CancellationToken() {
85+
override fun onCanceledRequested(p0: OnTokenCanceledListener): CancellationToken {
86+
return CancellationTokenSource().token
87+
}
88+
89+
override fun isCancellationRequested(): Boolean {
90+
return false
91+
}
92+
}
93+
).addOnSuccessListener { location ->
94+
val lastLatitude = location.latitude
95+
val lastLongitude = location.longitude
96+
97+
runningRepository.setRunningState(
98+
RunningPosition(lastLatitude, lastLongitude)
99+
)
100+
}.addOnFailureListener {
101+
runningRepository.pauseRunning()
102+
}
103+
} catch (exception: SecurityException) {
104+
runningRepository.pauseRunning()
105+
} catch (e: Exception) {
106+
runningRepository.pauseRunning()
107+
}
108+
}
109+
110+
companion object {
111+
const val WORKER_NAME = "runningWorker"
112+
}
113+
}

0 commit comments

Comments
 (0)