Skip to content

Commit 38c6fe8

Browse files
committed
add CountDownTimer in CameraViewmodel FoKE-Developers#9
1 parent a5323e6 commit 38c6fe8

File tree

2 files changed

+119
-18
lines changed

2 files changed

+119
-18
lines changed

presenter/src/main/java/com/foke/together/presenter/screen/CameraScreen.kt

+75-18
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package com.foke.together.presenter.screen
22

3+
import android.graphics.Bitmap
4+
import android.graphics.Rect
35
import androidx.compose.foundation.clickable
46
import androidx.compose.foundation.layout.aspectRatio
57
import androidx.compose.foundation.layout.fillMaxSize
8+
import androidx.compose.material3.LinearProgressIndicator
69
import androidx.compose.material3.MaterialTheme
710
import androidx.compose.material3.Surface
811
import androidx.compose.material3.Text
@@ -14,17 +17,36 @@ import androidx.compose.ui.unit.dp
1417
import androidx.compose.ui.unit.sp
1518
import androidx.compose.ui.viewinterop.AndroidView
1619
import androidx.constraintlayout.compose.ConstraintLayout
20+
import androidx.constraintlayout.compose.Dimension
1721
import com.foke.together.presenter.theme.FourCutTogetherTheme
1822
import com.longdo.mjpegviewer.MjpegView
1923
import androidx.hilt.navigation.compose.hiltViewModel
24+
import androidx.lifecycle.Lifecycle
25+
import androidx.lifecycle.compose.LifecycleEventEffect
2026
import com.foke.together.presenter.viewmodel.CameraViewModel
27+
import com.foke.together.util.AppLog
28+
import com.longdo.mjpegviewer.MjpegViewError
29+
import com.longdo.mjpegviewer.MjpegViewStateChangeListener
2130

2231
@Composable
2332
fun CameraScreen(
2433
navigateToShare: () -> Unit,
2534
popBackStack: () -> Unit,
2635
viewModel: CameraViewModel = hiltViewModel()
2736
) {
37+
val TAG = "CameraScreen"
38+
LifecycleEventEffect(Lifecycle.Event.ON_START) {
39+
viewModel.setCaptureTimer { navigateToShare() }
40+
AppLog.d(TAG, "ON_START")
41+
}
42+
LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
43+
AppLog.d(TAG, "ON_RESUME")
44+
viewModel.startCaptureTimer()
45+
}
46+
LifecycleEventEffect(Lifecycle.Event.ON_STOP) {
47+
viewModel.stopCaptureTimer()
48+
AppLog.d(TAG, "ON_STOP")
49+
}
2850
ConstraintLayout(
2951
modifier = Modifier.fillMaxSize()
3052
) {
@@ -49,7 +71,15 @@ fun CameraScreen(
4971
// tint = MaterialTheme.colorScheme.primary
5072
// )
5173
// }
52-
74+
LinearProgressIndicator(
75+
progress = { viewModel.progressState },
76+
modifier = Modifier.constrainAs(progress){
77+
start.linkTo(parent.start, margin = 24.dp)
78+
end.linkTo(parent.end, margin = 24.dp)
79+
bottom.linkTo(title.top)
80+
width = Dimension.fillToConstraints
81+
},
82+
)
5383
Text(
5484
text = "촬영시 움직이지마세요",
5585
modifier = Modifier.constrainAs(title) {
@@ -62,36 +92,63 @@ fun CameraScreen(
6292
fontSize = 24.sp,
6393
)
6494

65-
AndroidView(
66-
modifier = Modifier.constrainAs(preview) {
67-
top.linkTo(title.bottom)
68-
start.linkTo(parent.start, margin = 24.dp)
69-
end.linkTo(parent.end, margin = 24.dp)
70-
bottom.linkTo(imageCount.top)
71-
}
95+
val mjpegPreview = AndroidView(
96+
modifier = Modifier
97+
.constrainAs(preview) {
98+
top.linkTo(title.bottom)
99+
start.linkTo(parent.start, margin = 24.dp)
100+
end.linkTo(parent.end, margin = 24.dp)
101+
bottom.linkTo(imageCount.top)
102+
}
72103
.aspectRatio(1.5f),
73104
factory = { context ->
74105
MjpegView(context).apply {
75106
mode = MjpegView.MODE_BEST_FIT
76107
isAdjustHeight = true
77108
supportPinchZoomAndPan = false
109+
stateChangeListener = object: MjpegViewStateChangeListener {
110+
override fun onStreamDownloadStart() {
111+
AppLog.d(TAG, "onStreamDownloadStart")
112+
}
113+
114+
override fun onStreamDownloadStop() {
115+
AppLog.d(TAG, "onStreamDownloadStop")
116+
}
117+
118+
override fun onServerConnected() {
119+
AppLog.d(TAG, "onServerConnected")
120+
}
121+
122+
override fun onMeasurementChanged(rect: Rect?) {
123+
AppLog.d(TAG, "onMeasurementChanged")
124+
}
125+
126+
override fun onNewFrame(image: Bitmap?) {
127+
AppLog.d(TAG, "onNewFrame")
128+
// stream 한장 받을때마다 오는 콜백
129+
}
130+
131+
override fun onError(error: MjpegViewError?) {
132+
AppLog.d(TAG, "onError, ${error.toString()}")
133+
}
134+
}
78135
// test url
79136
// TODO : change url in viewmodel
80-
setUrl("https://192.168.137.100:8080/test.mjpg")
137+
setUrl("http://10.32.100.37:5000/preview")
81138
startStream()
82139
}
83140
},
84141
)
142+
85143
Text(
86-
text = "1 / 4",
87-
modifier = Modifier.constrainAs(imageCount) {
88-
top.linkTo(preview.bottom)
89-
start.linkTo(parent.start)
90-
end.linkTo(parent.end)
91-
bottom.linkTo(parent.bottom)
92-
}
93-
// 네비게이션 테스트 코드
94-
.clickable { navigateToShare() },
144+
text = "${viewModel.captureCount} / 4",
145+
modifier = Modifier
146+
.constrainAs(imageCount) {
147+
top.linkTo(preview.bottom)
148+
start.linkTo(parent.start)
149+
end.linkTo(parent.end)
150+
bottom.linkTo(parent.bottom)
151+
},
95152
fontWeight = FontWeight.Bold,
96153
fontSize = 24.sp,
97154
)
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,55 @@
11
package com.foke.together.presenter.viewmodel
22

3+
import android.os.CountDownTimer
4+
import androidx.compose.runtime.getValue
5+
import androidx.compose.runtime.mutableFloatStateOf
6+
import androidx.compose.runtime.mutableIntStateOf
7+
import androidx.lifecycle.DefaultLifecycleObserver
8+
import androidx.lifecycle.LifecycleOwner
39
import androidx.lifecycle.ViewModel
10+
import androidx.lifecycle.viewModelScope
11+
import com.foke.together.util.AppLog
412
import dagger.hilt.android.lifecycle.HiltViewModel
13+
import kotlinx.coroutines.launch
514
import javax.inject.Inject
615

716
@HiltViewModel
817
class CameraViewModel @Inject constructor(
918
): ViewModel() {
1019
// TODO: add viewmodel code here
20+
private val _progressState = mutableFloatStateOf(1f)
21+
val progressState: Float by _progressState
22+
private val _captureCount = mutableIntStateOf(1)
23+
val captureCount: Int by _captureCount
24+
private var captureTimer: CountDownTimer? = null
25+
fun setCaptureTimer(nextNavigate: () -> Unit) {
26+
captureTimer = object : CountDownTimer(5000, 10) {
27+
override fun onTick(millisUntilFinished: Long) {
28+
_progressState.floatValue = 1f - (millisUntilFinished.toFloat() / 5000)
29+
AppLog.d("CameraViewModel", "onTick: ${_progressState.floatValue}")
30+
}
31+
override fun onFinish() {
32+
_progressState.floatValue = 1f
33+
if(_captureCount.intValue < 4){
34+
_captureCount.intValue += 1
35+
startCaptureTimer()
36+
AppLog.d("CameraViewModel", "onFinish: ${_captureCount.intValue}")
37+
}
38+
else {
39+
stopCaptureTimer()
40+
_captureCount.intValue = 1
41+
AppLog.d("CameraViewModel", "onFinish: ${_captureCount.intValue}")
42+
nextNavigate()
43+
}
44+
}
45+
}
46+
}
47+
48+
fun startCaptureTimer() = viewModelScope.launch{
49+
if(captureTimer != null) captureTimer!!.start()
50+
}
51+
fun stopCaptureTimer() = viewModelScope.launch{
52+
if(captureTimer != null) captureTimer!!.cancel()
53+
}
54+
1155
}

0 commit comments

Comments
 (0)