From df07194685d1be3e9658f181417bd0b756cde48f Mon Sep 17 00:00:00 2001 From: Junyoung-WON Date: Wed, 23 Oct 2024 15:19:57 +0900 Subject: [PATCH 1/8] =?UTF-8?q?build:=20androidx=20camera=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 버전 카탈로그 활용 --- android/Staccato_AN/app/build.gradle.kts | 7 +++++++ android/Staccato_AN/gradle/libs.versions.toml | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/android/Staccato_AN/app/build.gradle.kts b/android/Staccato_AN/app/build.gradle.kts index b3ead0262..50199b158 100644 --- a/android/Staccato_AN/app/build.gradle.kts +++ b/android/Staccato_AN/app/build.gradle.kts @@ -165,6 +165,13 @@ dependencies { // Lottie implementation(libs.lottie) + + // CameraX + implementation(libs.androidx.camera.core) + implementation(libs.androidx.camera.camera2) + implementation(libs.androidx.camera.lifecycle) + implementation(libs.androidx.camera.view) + implementation(libs.androidx.camera.extension) } secrets { diff --git a/android/Staccato_AN/gradle/libs.versions.toml b/android/Staccato_AN/gradle/libs.versions.toml index 5889126b1..089498d28 100644 --- a/android/Staccato_AN/gradle/libs.versions.toml +++ b/android/Staccato_AN/gradle/libs.versions.toml @@ -36,6 +36,7 @@ crashlytics = "3.0.2" mapsplatformSecretsGradlePlugin = "2.0.1" playServicesMaps = "19.0.0" viewpager2 = "1.1.0" +camerax = "1.1.0-beta01" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -76,6 +77,11 @@ coil = { group = "io.coil-kt", name = "coil", version.ref = "coil" } androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigation" } androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigation" } play-services-maps = { group = "com.google.android.gms", name = "play-services-maps", version.ref = "playServicesMaps" } +androidx-camera-core = { group = "androidx.camera", name = "camera-core", version.ref = "camerax" } +androidx-camera-camera2 = { group = "androidx.camera", name = "camera-camera2", version.ref = "camerax" } +androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camerax" } +androidx-camera-view = { group = "androidx.camera", name = "camera-view", version.ref = "camerax" } +androidx-camera-extension = { group = "androidx.camera", name = "camera-extensions", version.ref = "camerax" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } From 1169c3664c6301077f61da377b159308ff8aeba3 Mon Sep 17 00:00:00 2001 From: Junyoung-WON Date: Wed, 23 Oct 2024 15:20:28 +0900 Subject: [PATCH 2/8] =?UTF-8?q?build:=20AndroidManifest=20=EC=B9=B4?= =?UTF-8?q?=EB=A9=94=EB=9D=BC=20=EC=A0=91=EA=B7=BC=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - android.hardware.camera.any 로 설정하여 전, 후면 모두 사용 가능하도록 변경 --- android/Staccato_AN/app/src/main/AndroidManifest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/android/Staccato_AN/app/src/main/AndroidManifest.xml b/android/Staccato_AN/app/src/main/AndroidManifest.xml index c10b1bacf..d20f936bc 100644 --- a/android/Staccato_AN/app/src/main/AndroidManifest.xml +++ b/android/Staccato_AN/app/src/main/AndroidManifest.xml @@ -11,9 +11,9 @@ - + @@ -24,7 +24,7 @@ - + Date: Thu, 24 Oct 2024 13:28:32 +0900 Subject: [PATCH 3/8] =?UTF-8?q?ui:=20=EC=82=AC=EC=A7=84=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EB=8B=A4=EC=9D=B4=EC=96=BC=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=97=90=EC=84=9C=20=E3=84=B7=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=A0=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EB=A6=AC=EC=86=8C?= =?UTF-8?q?=EC=8A=A4=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 권한 관련 안내 메시지 추가 --- android/Staccato_AN/app/src/main/res/values/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/android/Staccato_AN/app/src/main/res/values/strings.xml b/android/Staccato_AN/app/src/main/res/values/strings.xml index 8a00eb8ea..7a3ccb7d2 100644 --- a/android/Staccato_AN/app/src/main/res/values/strings.xml +++ b/android/Staccato_AN/app/src/main/res/values/strings.xml @@ -154,11 +154,17 @@ 프로필 이미지 수정 인스타그램으로 이동 + // activity_camera_preview + 촬영된 이미지 미리 보기 + // fragment_photo_attach 사진을 등록해 주세요 카메라 열기 앨범에서 가져오기 사진 및 동영상 액세스 권한을 허용해 주세요. + 카메라 실행 중 에러가 발생했습니다.\n잠시 후에 다시 시도해주세요. + 사진을 불러올 수 없습니다.\n잠시 후에 다시 시도해주세요. + 실행할 수 있는 카메라 앱이 없습니다. 설정으로 이동하기 // dialog_delete_impossibility From 750df2adb7d52d133e106137a8732e8630bddda7 Mon Sep 17 00:00:00 2001 From: Junyoung-WON Date: Thu, 24 Oct 2024 13:29:27 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=EC=B9=B4=EB=A9=94=EB=9D=BC=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 접근 권한 확인 후 카메라 실행 - 카메라에서 촬영한 사진을 가져와 Activity에게 이미지 URI 전달 --- .../common/PhotoAttachFragment.kt | 242 +++++++++++++----- 1 file changed, 174 insertions(+), 68 deletions(-) diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt index 706d2213b..001210a66 100644 --- a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt +++ b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt @@ -1,8 +1,11 @@ package com.on.staccato.presentation.common +import android.Manifest import android.Manifest.permission.READ_EXTERNAL_STORAGE import android.Manifest.permission.READ_MEDIA_IMAGES import android.app.Activity.RESULT_OK +import android.content.ActivityNotFoundException +import android.content.ContentValues import android.content.Context import android.content.Intent import android.content.pm.PackageManager @@ -16,14 +19,17 @@ import android.view.View import android.view.ViewGroup import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts +import androidx.annotation.StringRes import androidx.core.content.ContextCompat import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.snackbar.Snackbar import com.on.staccato.R import com.on.staccato.databinding.FragmentPhotoAttachBinding import com.on.staccato.presentation.staccatocreation.OnUrisSelectedListener -import com.on.staccato.presentation.util.showToast import dagger.hilt.android.AndroidEntryPoint +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale @AndroidEntryPoint class PhotoAttachFragment : BottomSheetDialogFragment(), PhotoAttachHandler { @@ -31,17 +37,59 @@ class PhotoAttachFragment : BottomSheetDialogFragment(), PhotoAttachHandler { private val binding get() = _binding!! private lateinit var uriSelectedListener: OnUrisSelectedListener - private lateinit var requestPermissionLauncher: ActivityResultLauncher + private lateinit var requestGalleryPermissionLauncher: ActivityResultLauncher> + private lateinit var requestCameraPermissionLauncher: ActivityResultLauncher> private lateinit var galleryLauncher: ActivityResultLauncher + private lateinit var cameraLauncher: ActivityResultLauncher private var multipleAbleOption: Boolean = false + private var currentImageUri: Uri? = null override fun onAttach(context: Context) { super.onAttach(context) initUrisSelectedListener(context) initRequestPermissionLauncher() + initCameraLauncher() initGalleryLauncher() } + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View { + _binding = FragmentPhotoAttachBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated( + view: View, + savedInstanceState: Bundle?, + ) { + binding.handler = this + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + currentImageUri = null + } + + override fun onCameraClicked() { + checkPermissionsAndLaunch( + permissions = CAMERA_REQUIRED_PERMISSIONS, + requestPermissionLauncherOnNotGranted = requestCameraPermissionLauncher, + onGranted = { startCamera() } + ) + } + + override fun onGalleryClicked() { + checkPermissionsAndLaunch( + permissions = arrayOf(GALLERY_REQUIRED_PERMISSION), + requestPermissionLauncherOnNotGranted = requestGalleryPermissionLauncher, + onGranted = { launchGallery() }, + ) + } + fun setMultipleAbleOption(option: Boolean) { multipleAbleOption = option } @@ -55,16 +103,67 @@ class PhotoAttachFragment : BottomSheetDialogFragment(), PhotoAttachHandler { } private fun initRequestPermissionLauncher() { - requestPermissionLauncher = - registerForActivityResult(ActivityResultContracts.RequestPermission()) { isPermissionGranted -> - if (isPermissionGranted) { - launchGallery() - } else { - showPermissionSnackBar() + requestCameraPermissionLauncher = buildRequestPermissionLauncher { startCamera() } + requestGalleryPermissionLauncher = buildRequestPermissionLauncher { launchGallery() } + } + + private fun initCameraLauncher() { + cameraLauncher = + registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess -> + val imageUri = currentImageUri + if (isSuccess && imageUri != null) { + uriSelectedListener.onUrisSelected(imageUri) + dismiss() } } } + private fun initGalleryLauncher() { + galleryLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (result.resultCode == RESULT_OK) { + val imageUris = extractImageUris(result.data) + if (imageUris.isNotEmpty()) { + uriSelectedListener.onUrisSelected(*imageUris.toTypedArray()) + dismiss() + } else { + showGalleryErrorSnackBar() + } + } + } + } + + private fun buildRequestPermissionLauncher( + actionOnPermissionGranted: () -> Unit, + ): ActivityResultLauncher> = + registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions -> + if (permissions.all { (_, isGranted) -> isGranted }) { + actionOnPermissionGranted() + } else { + showPermissionSnackBar() + } + } + + private fun startCamera() { + val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) + if (takePictureIntent.resolveActivity(requireActivity().packageManager) != null) { + launchCamera() + } else { + showNoCameraSnackBar() + } + } + + private fun launchCamera() { + try { + currentImageUri = createImageUri() + currentImageUri?.let { imageUri -> + cameraLauncher.launch(imageUri) + } + } catch (e: ActivityNotFoundException) { + showCameraErrorSnackBar() + } + } + private fun launchGallery() { val intent = Intent(Intent.ACTION_PICK) @@ -73,16 +172,54 @@ class PhotoAttachFragment : BottomSheetDialogFragment(), PhotoAttachHandler { galleryLauncher.launch(intent) } + private fun checkPermissionsAndLaunch( + permissions: Array, + requestPermissionLauncherOnNotGranted: ActivityResultLauncher>, + onGranted: () -> Unit, + ) { + val isPermissionGranted = + permissions.all { permission -> + ContextCompat.checkSelfPermission( + requireContext(), permission, + ) == PackageManager.PERMISSION_GRANTED + } + if (isPermissionGranted) { + onGranted() + } else { + requestPermissionLauncherOnNotGranted.launch(permissions) + } + } + private fun showPermissionSnackBar() { - val snackBar = makeSnackBar() + showSnackBar(R.string.snack_bar_require_photo_album_permission) + } + + private fun showCameraErrorSnackBar() { + showSnackBar(R.string.snack_bar_camera_error) + } + + private fun showGalleryErrorSnackBar() { + showSnackBar(R.string.snack_bar_gallery_error) + } + + private fun showNoCameraSnackBar() { + showSnackBar(R.string.snack_bar_no_camera) + } + + private fun showSnackBar( + @StringRes resId: Int, + ) { + val snackBar = makeSnackBar(resId) setSnackBarAction(snackBar) snackBar.show() } - private fun makeSnackBar(): Snackbar { + private fun makeSnackBar( + @StringRes resId: Int, + ): Snackbar { return Snackbar.make( binding.root, - R.string.snack_bar_require_photo_album_permission, + resId, Snackbar.LENGTH_LONG, ) } @@ -95,21 +232,6 @@ class PhotoAttachFragment : BottomSheetDialogFragment(), PhotoAttachHandler { } } - private fun initGalleryLauncher() { - galleryLauncher = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - if (result.resultCode == RESULT_OK) { - val imageUris = extractImageUris(result.data) - if (imageUris.isNotEmpty()) { - uriSelectedListener.onUrisSelected(*imageUris.toTypedArray()) - dismiss() - } else { - showToast("사진을 불러올 수 없습니다.") - } - } - } - } - private fun extractImageUris(intent: Intent?): List { val imageUris = mutableListOf() intent?.let { @@ -124,54 +246,38 @@ class PhotoAttachFragment : BottomSheetDialogFragment(), PhotoAttachHandler { return imageUris } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View { - _binding = FragmentPhotoAttachBinding.inflate(inflater, container, false) - return binding.root - } - - override fun onViewCreated( - view: View, - savedInstanceState: Bundle?, - ) { - binding.handler = this - } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - - override fun onCameraClicked() { - showToast(getString(R.string.all_default_not_supported)) - } - - override fun onGalleryClicked() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - checkPermissionsAndLaunch(READ_MEDIA_IMAGES) - } else { - checkPermissionsAndLaunch(READ_EXTERNAL_STORAGE) - } + private fun createImageUri(): Uri? { + val timeStamp = SimpleDateFormat(FILENAME_DATE_FORMAT, Locale.KOREA).format(Date()) + val content = createImageContent(timeStamp) + return requireActivity().contentResolver.insert( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + content, + ) } - private fun checkPermissionsAndLaunch(permission: String) { - val isPermissionGranted = - ContextCompat.checkSelfPermission( - requireContext(), - permission, - ) == PackageManager.PERMISSION_GRANTED - if (isPermissionGranted) { - launchGallery() - } else { - requestPermissionLauncher.launch(permission) + private fun createImageContent(fileName: String): ContentValues = + ContentValues().apply { + put(MediaStore.Images.Media.DISPLAY_NAME, "img_$fileName.jpg") + put(MediaStore.Images.Media.MIME_TYPE, "image/jpg") } - } companion object { const val TAG = "PhotoAttachModalBottomSheet" const val PACKAGE_SCHEME = "package" + private const val FILENAME_DATE_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS" + private val CAMERA_REQUIRED_PERMISSIONS = + mutableListOf( + Manifest.permission.CAMERA, + ).apply { + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { + add(Manifest.permission.WRITE_EXTERNAL_STORAGE) + } + }.toTypedArray() + private val GALLERY_REQUIRED_PERMISSION = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + READ_MEDIA_IMAGES + } else { + READ_EXTERNAL_STORAGE + } } } From fbb7b1a8d2fe846c16313fd920c8ac81c2f2dc25 Mon Sep 17 00:00:00 2001 From: Junyoung-WON Date: Thu, 24 Oct 2024 14:24:39 +0900 Subject: [PATCH 5/8] =?UTF-8?q?style:=20ktlint=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../on/staccato/presentation/common/PhotoAttachFragment.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt index 001210a66..5f3de07d9 100644 --- a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt +++ b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt @@ -78,7 +78,7 @@ class PhotoAttachFragment : BottomSheetDialogFragment(), PhotoAttachHandler { checkPermissionsAndLaunch( permissions = CAMERA_REQUIRED_PERMISSIONS, requestPermissionLauncherOnNotGranted = requestCameraPermissionLauncher, - onGranted = { startCamera() } + onGranted = { startCamera() }, ) } @@ -133,9 +133,7 @@ class PhotoAttachFragment : BottomSheetDialogFragment(), PhotoAttachHandler { } } - private fun buildRequestPermissionLauncher( - actionOnPermissionGranted: () -> Unit, - ): ActivityResultLauncher> = + private fun buildRequestPermissionLauncher(actionOnPermissionGranted: () -> Unit): ActivityResultLauncher> = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions -> if (permissions.all { (_, isGranted) -> isGranted }) { actionOnPermissionGranted() From 0c223f9c85a5d72088d82daa344b87f30e0ea310 Mon Sep 17 00:00:00 2001 From: Junyoung-WON Date: Thu, 24 Oct 2024 14:44:56 +0900 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20=EA=B6=8C=ED=95=9C=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EC=8A=A4=EB=82=B5=EB=B0=94=EC=99=80=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=8A=A4=EB=82=B5?= =?UTF-8?q?=EB=B0=94=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/common/PhotoAttachFragment.kt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt index 5f3de07d9..39483ae29 100644 --- a/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt +++ b/android/Staccato_AN/app/src/main/java/com/on/staccato/presentation/common/PhotoAttachFragment.kt @@ -189,7 +189,7 @@ class PhotoAttachFragment : BottomSheetDialogFragment(), PhotoAttachHandler { } private fun showPermissionSnackBar() { - showSnackBar(R.string.snack_bar_require_photo_album_permission) + showSettingSnackBar(R.string.snack_bar_require_photo_album_permission) } private fun showCameraErrorSnackBar() { @@ -208,7 +208,14 @@ class PhotoAttachFragment : BottomSheetDialogFragment(), PhotoAttachHandler { @StringRes resId: Int, ) { val snackBar = makeSnackBar(resId) - setSnackBarAction(snackBar) + snackBar.show() + } + + private fun showSettingSnackBar( + @StringRes resId: Int, + ) { + val snackBar = makeSnackBar(resId) + setSnackBarActionMoveToSetting(snackBar) snackBar.show() } @@ -222,7 +229,7 @@ class PhotoAttachFragment : BottomSheetDialogFragment(), PhotoAttachHandler { ) } - private fun setSnackBarAction(snackBar: Snackbar) { + private fun setSnackBarActionMoveToSetting(snackBar: Snackbar) { snackBar.setAction(R.string.snack_bar_move_to_setting) { val uri = Uri.fromParts(PACKAGE_SCHEME, requireContext().packageName, null) val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(uri) From 37db12f284b136bf774f3867cf3f7b57c57f0212 Mon Sep 17 00:00:00 2001 From: Junyoung-WON Date: Thu, 24 Oct 2024 15:29:17 +0900 Subject: [PATCH 7/8] =?UTF-8?q?ui:=20=EA=B6=8C=ED=95=9C=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EC=8A=A4=EB=82=B5=EB=B0=94=EC=9D=98=20=EB=AC=B8?= =?UTF-8?q?=EA=B5=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/Staccato_AN/app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/Staccato_AN/app/src/main/res/values/strings.xml b/android/Staccato_AN/app/src/main/res/values/strings.xml index 7a3ccb7d2..c09bb318a 100644 --- a/android/Staccato_AN/app/src/main/res/values/strings.xml +++ b/android/Staccato_AN/app/src/main/res/values/strings.xml @@ -161,7 +161,7 @@ 사진을 등록해 주세요 카메라 열기 앨범에서 가져오기 - 사진 및 동영상 액세스 권한을 허용해 주세요. + 카메라와 사진 및 동영상 접근 권한이 필요합니다.\n설정에서 권한을 허용해 주세요. 카메라 실행 중 에러가 발생했습니다.\n잠시 후에 다시 시도해주세요. 사진을 불러올 수 없습니다.\n잠시 후에 다시 시도해주세요. 실행할 수 있는 카메라 앱이 없습니다. From 43332fe8e0ab51ff27b9b4082a8717c2fe590f91 Mon Sep 17 00:00:00 2001 From: Junyoung-WON Date: Thu, 24 Oct 2024 15:45:17 +0900 Subject: [PATCH 8/8] =?UTF-8?q?fix:=20=EC=99=B8=EB=B6=80=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EC=86=8C=20=EC=93=B0=EA=B8=B0=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/Staccato_AN/app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/android/Staccato_AN/app/src/main/AndroidManifest.xml b/android/Staccato_AN/app/src/main/AndroidManifest.xml index d20f936bc..d5c54f8c8 100644 --- a/android/Staccato_AN/app/src/main/AndroidManifest.xml +++ b/android/Staccato_AN/app/src/main/AndroidManifest.xml @@ -26,6 +26,7 @@ +