Skip to content

Commit 42934fd

Browse files
committed
[feat] #62 get galley video
1 parent 3b9cc8e commit 42934fd

File tree

6 files changed

+180
-76
lines changed

6 files changed

+180
-76
lines changed

app/src/main/AndroidManifest.xml

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
xmlns:tools="http://schemas.android.com/tools">
44

55
<uses-permission android:name="android.permission.INTERNET"/>
6+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
7+
android:maxSdkVersion="32" />
8+
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" android:minSdkVersion="33" />
9+
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" android:minSdkVersion="33" />
610

711
<application
812
android:name=".RecordyApplication"

feature/navigator/src/main/java/com/record/navigator/MainScreen.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ internal fun MainScreen(
8383

8484
uploadNavGraph(
8585
padding = innerPadding,
86-
navigateSelectedKeyword = navigator::navigateSelectedKeyword,
86+
navigateSelectedVideo = navigator::navigateSelectedVideo,
8787
navigateDefinedContent = navigator::navigateDefinedContent,
8888
navigateCompletedUpload = navigator::navigateCompletedUpload,
8989
)

feature/upload/src/main/java/com/record/upload/SelectedKeywordScreen.kt

-58
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package com.record.upload
2+
3+
import android.content.ContentUris
4+
import android.content.Context
5+
import android.database.Cursor
6+
import android.net.Uri
7+
import android.provider.MediaStore
8+
import android.util.Log
9+
import androidx.compose.foundation.background
10+
import androidx.compose.foundation.layout.Box
11+
import androidx.compose.foundation.layout.Column
12+
import androidx.compose.foundation.layout.PaddingValues
13+
import androidx.compose.foundation.layout.fillMaxSize
14+
import androidx.compose.foundation.layout.fillMaxWidth
15+
import androidx.compose.material3.Text
16+
import androidx.compose.runtime.Composable
17+
import androidx.compose.ui.Alignment
18+
import androidx.compose.ui.Modifier
19+
import androidx.compose.ui.platform.LocalContext
20+
import androidx.compose.ui.text.intl.Locale
21+
import androidx.compose.ui.text.style.TextAlign
22+
import androidx.compose.ui.tooling.preview.Preview
23+
import com.record.designsystem.component.button.RecordyButton
24+
import com.record.designsystem.component.navbar.TopNavigationBar
25+
import com.record.designsystem.theme.Background
26+
import com.record.designsystem.theme.Gray03
27+
import com.record.designsystem.theme.RecordyTheme
28+
29+
@Composable
30+
fun SelectedVideoRoute(
31+
paddingValues: PaddingValues,
32+
navigateDefinedContent: () -> Unit,
33+
) {
34+
SelectedVideoScreen(navigateDefinedContent = navigateDefinedContent)
35+
}
36+
37+
@Composable
38+
fun SelectedVideoScreen(
39+
navigateDefinedContent: () -> Unit,
40+
) { Log.d("images","${getAllVideos(10, null, LocalContext.current)}")
41+
Box(
42+
modifier = Modifier
43+
.fillMaxSize()
44+
.background(Background),
45+
) {
46+
Column(
47+
modifier = Modifier
48+
.align(Alignment.TopCenter),
49+
) {
50+
TopNavigationBar(title = "영상 선택", enableGradation = true)
51+
Text(
52+
text = "ⓘ 1080p 이하의 최대 15초 영상을 올려주세요.",
53+
color = Gray03,
54+
style = RecordyTheme.typography.caption2,
55+
maxLines = 1,
56+
modifier = Modifier.fillMaxWidth(),
57+
textAlign = TextAlign.Center,
58+
)
59+
}
60+
RecordyButton(
61+
modifier = Modifier.align(Alignment.BottomCenter),
62+
text = "다음",
63+
enabled = true,
64+
onClick = {},
65+
)
66+
}
67+
68+
}
69+
@Preview
70+
@Composable
71+
fun SelectedVideoScreenPreview() {
72+
RecordyTheme {
73+
VideoPickerScreen(navigateSelectedVideo = { /*TODO*/ })
74+
}
75+
}
76+
77+
fun getAllVideos(
78+
loadSize: Int,
79+
currentLocation: String?,
80+
context: Context
81+
): MutableList<GalleryVideo> {
82+
val galleryVideoList = mutableListOf<GalleryVideo>()
83+
// 외장 메모리에 있는 비디오 파일의 URI를 받도록 함
84+
val uriExternal: Uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
85+
// 커서에 가져올 정보에 대해서 지정한다.
86+
val projection = arrayOf(
87+
MediaStore.Video.VideoColumns.DATA,
88+
MediaStore.Video.VideoColumns.DISPLAY_NAME, // 이름
89+
MediaStore.Video.VideoColumns.SIZE, // 크기
90+
MediaStore.Video.VideoColumns.DATE_TAKEN,
91+
MediaStore.Video.VideoColumns.DATE_ADDED, // 추가된 날짜
92+
MediaStore.Video.VideoColumns._ID
93+
)
94+
val resolver = context.contentResolver
95+
96+
var selection: String? = null
97+
var selectionArgs: Array<String>? = null
98+
99+
val query = resolver.query(
100+
uriExternal,
101+
projection,
102+
selection,
103+
selectionArgs,
104+
"${MediaStore.Video.VideoColumns.DATE_ADDED} DESC"
105+
)
106+
107+
query?.use { cursor ->
108+
Log.d("gallery cursor", "Cursor count: ${cursor.count}.")
109+
110+
if (cursor.moveToFirst()) {
111+
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.VideoColumns._ID)
112+
val nameColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.VideoColumns.DISPLAY_NAME)
113+
val filePathColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.VideoColumns.DATA)
114+
val sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.VideoColumns.SIZE)
115+
val dateColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.VideoColumns.DATE_TAKEN)
116+
117+
do {
118+
val id = cursor.getLong(idColumn)
119+
val filepath = cursor.getString(filePathColumn)
120+
val name = cursor.getString(nameColumn)
121+
val size = cursor.getInt(sizeColumn)
122+
val date = cursor.getString(dateColumn)
123+
124+
val contentUri = ContentUris.withAppendedId(uriExternal, id)
125+
Log.d("gallery contentUri", "$contentUri")
126+
galleryVideoList.add(
127+
GalleryVideo(
128+
id,
129+
filepath = filepath,
130+
uri = contentUri,
131+
name = name,
132+
date = date ?: "",
133+
size = size
134+
)
135+
)
136+
} while (cursor.moveToNext())
137+
}
138+
}
139+
140+
return galleryVideoList
141+
}
142+
143+
data class GalleryVideo(
144+
val id: Long,
145+
val filepath: String,
146+
val uri: Uri,
147+
val name: String,
148+
val date: String,
149+
val size: Int
150+
)

feature/upload/src/main/java/com/record/upload/VideoPickerScreen.kt

+17-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.record.upload
22

3+
import android.content.Intent
4+
import androidx.activity.compose.rememberLauncherForActivityResult
5+
import androidx.activity.result.contract.ActivityResultContracts
36
import androidx.compose.foundation.Image
47
import androidx.compose.foundation.background
58
import androidx.compose.foundation.layout.Arrangement
@@ -18,9 +21,11 @@ import androidx.compose.runtime.Composable
1821
import androidx.compose.runtime.getValue
1922
import androidx.compose.runtime.mutableStateOf
2023
import androidx.compose.runtime.remember
24+
import androidx.compose.runtime.rememberCoroutineScope
2125
import androidx.compose.runtime.setValue
2226
import androidx.compose.ui.Alignment
2327
import androidx.compose.ui.Modifier
28+
import androidx.compose.ui.platform.LocalContext
2429
import androidx.compose.ui.res.painterResource
2530
import androidx.compose.ui.text.style.TextAlign
2631
import androidx.compose.ui.tooling.preview.Preview
@@ -32,26 +37,29 @@ import com.record.designsystem.component.textfield.RecordyBasicTextField
3237
import com.record.designsystem.theme.Background
3338
import com.record.designsystem.theme.RecordyTheme
3439
import com.record.ui.extension.customClickable
40+
import kotlinx.coroutines.launch
3541
import timber.log.Timber
3642

3743
@Composable
3844
fun VideoPickerRoute(
3945
paddingValues: PaddingValues,
40-
navigateSelectedKeyword: () -> Unit,
46+
navigateSelectedVideo: () -> Unit,
4147
) {
4248
VideoPickerScreen(
43-
navigateSelectedKeyword = navigateSelectedKeyword,
44-
onClickPickVideo = {},
49+
navigateSelectedVideo = navigateSelectedVideo,
4550
onClickKeyword = {}
4651
)
4752
}
4853

4954
@Composable
5055
fun VideoPickerScreen(
51-
navigateSelectedKeyword: () -> Unit,
52-
onClickPickVideo: () -> Unit = {},
56+
navigateSelectedVideo: () -> Unit,
5357
onClickKeyword: () -> Unit = {},
5458
) {
59+
60+
val context = LocalContext.current
61+
val scope = rememberCoroutineScope()
62+
5563
var normalValue by remember {
5664
mutableStateOf("")
5765
}
@@ -65,7 +73,7 @@ fun VideoPickerScreen(
6573
.align(Alignment.TopCenter)
6674
.verticalScroll(rememberScrollState()),
6775
) {
68-
TopNavigationBar(title = "영상 선택", enableGradation = true)
76+
TopNavigationBar(title = "내용 작성", enableGradation = true)
6977
Text(
7078
text = "ⓘ 주제와 무관한 기록은 무통보로 삭제될 수 있습니다",
7179
color = RecordyTheme.colors.gray03,
@@ -83,7 +91,7 @@ fun VideoPickerScreen(
8391
Box(
8492
modifier = Modifier
8593
.background(RecordyTheme.colors.gray08, shape = RoundedCornerShape(16.dp))
86-
.customClickable(onClick = onClickPickVideo),
94+
.customClickable(onClick = navigateSelectedVideo),
8795
) {
8896
Column(
8997
modifier = Modifier
@@ -98,7 +106,7 @@ fun VideoPickerScreen(
98106
modifier = Modifier.padding(bottom = 12.dp)
99107
)
100108
Text(
101-
text = "내용 작성",
109+
text = "영상 선택",
102110
color = RecordyTheme.colors.white,
103111
style = RecordyTheme.typography.subtitle,
104112
)
@@ -170,6 +178,6 @@ fun VideoPickerScreen(
170178
@Composable
171179
fun VideoPickerScreenPreview() {
172180
RecordyTheme {
173-
VideoPickerScreen(navigateSelectedKeyword = { /*TODO*/ })
181+
VideoPickerScreen(navigateSelectedVideo = { /*TODO*/ })
174182
}
175183
}

feature/upload/src/main/java/com/record/upload/navigation/UploadNavigation.kt

+8-8
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import androidx.navigation.NavOptions
88
import androidx.navigation.compose.composable
99
import com.record.upload.CompletedUploadRoute
1010
import com.record.upload.DefinedContentRoute
11-
import com.record.upload.SelectedKeywordRoute
11+
import com.record.upload.SelectedVideoRoute
1212
import com.record.upload.VideoPickerRoute
1313

1414
fun NavController.navigateUpload(navOptions: NavOptions) {
1515
navigate(UploadRoute.ROUTE, navOptions)
1616
}
17-
fun NavController.navigateSelectedKeyword() {
18-
navigate(UploadRoute.SELECTED_KEYWORD)
17+
fun NavController.navigateSelectedVideo() {
18+
navigate(UploadRoute.SELECTED_VIDEO)
1919
}
2020
fun NavController.navigateDefinedContent() {
2121
navigate(UploadRoute.DEFINED_CONTENT)
@@ -27,18 +27,18 @@ fun NavController.navigateCompletedUpload() {
2727
fun NavGraphBuilder.uploadNavGraph(
2828
padding: PaddingValues,
2929
modifier: Modifier = Modifier,
30-
navigateSelectedKeyword: () -> Unit,
30+
navigateSelectedVideo: () -> Unit,
3131
navigateDefinedContent: () -> Unit,
3232
navigateCompletedUpload: () -> Unit,
3333
) {
3434
composable(route = UploadRoute.ROUTE) {
3535
VideoPickerRoute(
3636
paddingValues = padding,
37-
navigateSelectedKeyword = navigateSelectedKeyword,
37+
navigateSelectedVideo = navigateSelectedVideo,
3838
)
3939
}
40-
composable(route = UploadRoute.SELECTED_KEYWORD) {
41-
SelectedKeywordRoute(
40+
composable(route = UploadRoute.SELECTED_VIDEO) {
41+
SelectedVideoRoute(
4242
paddingValues = padding,
4343
navigateDefinedContent = navigateDefinedContent,
4444
)
@@ -58,7 +58,7 @@ fun NavGraphBuilder.uploadNavGraph(
5858

5959
object UploadRoute {
6060
const val ROUTE = "upload"
61-
const val SELECTED_KEYWORD = "selected-keyword"
61+
const val SELECTED_VIDEO = "selected-video"
6262
const val DEFINED_CONTENT = "defined-content"
6363
const val COMPLETED_UPLOAD = "completed-upload"
6464
}

0 commit comments

Comments
 (0)