From 4e0a9e1c8707c52fa1e58dc59f6958fe407a5c21 Mon Sep 17 00:00:00 2001 From: easyhz Date: Thu, 11 Apr 2024 16:52:39 +0900 Subject: [PATCH] =?UTF-8?q?update:=20=EC=99=B8=EB=B6=80=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EA=B3=B5=EC=9C=A0=20=EB=B2=84=ED=8A=BC=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=B6=88=EB=9F=AC=EC=98=A4?= =?UTF-8?q?=EA=B8=B0=20=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 --- app/src/main/AndroidManifest.xml | 20 ++++++++- .../java/com/easyhz/picly/MainActivity.kt | 26 ++++++++--- .../picly/data/entity/gallery/GalleryImage.kt | 2 +- .../domain/model/album/IncomingImages.kt | 8 ++++ .../album/upload/gallery/GalleryImageItem.kt | 2 +- .../picly/provider/PiclyFileProvider.kt | 29 ++++++++++++ .../java/com/easyhz/picly/util/Extensions.kt | 45 ++++++++++++++++--- .../com/easyhz/picly/view/StartActivity.kt | 35 +++++++++++++++ .../picly/view/album/upload/UploadFragment.kt | 35 ++++++++++++--- .../view/navigation/NavControllerManager.kt | 8 +++- app/src/main/res/navigation/nav_graph.xml | 3 +- app/src/main/res/navigation/nav_main.xml | 7 +++ app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/file_paths.xml | 9 ++++ 14 files changed, 210 insertions(+), 20 deletions(-) create mode 100644 app/src/main/java/com/easyhz/picly/domain/model/album/IncomingImages.kt create mode 100644 app/src/main/java/com/easyhz/picly/provider/PiclyFileProvider.kt create mode 100644 app/src/main/res/xml/file_paths.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c633619..6211136 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,18 +19,36 @@ android:supportsRtl="true" android:theme="@style/Theme.Picly" tools:targetApi="31"> + + + + android:exported="true" + android:launchMode="singleTop" + > + + + + + + diff --git a/app/src/main/java/com/easyhz/picly/MainActivity.kt b/app/src/main/java/com/easyhz/picly/MainActivity.kt index 582f85e..46b650d 100644 --- a/app/src/main/java/com/easyhz/picly/MainActivity.kt +++ b/app/src/main/java/com/easyhz/picly/MainActivity.kt @@ -1,16 +1,16 @@ package com.easyhz.picly +import android.net.Uri +import android.os.Build import androidx.appcompat.app.AppCompatActivity import android.os.Bundle -import androidx.activity.viewModels -import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.navigation.fragment.NavHostFragment +import com.easyhz.picly.data.repository.user.UserManager import com.easyhz.picly.databinding.ActivityMainBinding -import com.easyhz.picly.view.MainViewModel +import com.easyhz.picly.domain.model.album.IncomingImages +import com.easyhz.picly.util.BlueSnackBar import com.easyhz.picly.view.navigation.NavControllerManager import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch @AndroidEntryPoint class MainActivity : AppCompatActivity() { @@ -29,6 +29,22 @@ class MainActivity : AppCompatActivity() { private fun initNavControllerManager(isFirstRun: Boolean) { val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragment) as NavHostFragment NavControllerManager.init(navHostFragment.navController, isFirstRun) + if (!isFirstRun && UserManager.isLoggedIn()) getIncomingImages() + } + + private fun getIncomingImages() { + val incomingImages = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + intent.getParcelableArrayListExtra("incomingImages", Uri::class.java) + } else { + @Suppress("DEPRECATION") + intent.getParcelableArrayListExtra("incomingImages") + } + if (incomingImages.isNullOrEmpty()) return + if (incomingImages.size > 10) { + BlueSnackBar.make(binding.root, getString(R.string.over_selected)).show() + return + } + NavControllerManager.navigateMainToUploadWithIncoming(IncomingImages().apply { addAll(incomingImages) }) } } \ No newline at end of file diff --git a/app/src/main/java/com/easyhz/picly/data/entity/gallery/GalleryImage.kt b/app/src/main/java/com/easyhz/picly/data/entity/gallery/GalleryImage.kt index 1a9f61f..9b2a407 100644 --- a/app/src/main/java/com/easyhz/picly/data/entity/gallery/GalleryImage.kt +++ b/app/src/main/java/com/easyhz/picly/data/entity/gallery/GalleryImage.kt @@ -44,7 +44,7 @@ data class GalleryImage( ) } - fun createFromCursor(cursor: Cursor, uri: Uri, context: Context): GalleryImage { + suspend fun createFromCursor(cursor: Cursor, uri: Uri, context: Context): GalleryImage { val id = cursor.getLongColumnOrThrow(MediaStore.Images.ImageColumns._ID) ?: -1 val name = cursor.getStringColumnOrThrow(MediaStore.Images.ImageColumns.DISPLAY_NAME) val path = cursor.getStringColumnOrThrow(MediaStore.Images.ImageColumns.DATA) diff --git a/app/src/main/java/com/easyhz/picly/domain/model/album/IncomingImages.kt b/app/src/main/java/com/easyhz/picly/domain/model/album/IncomingImages.kt new file mode 100644 index 0000000..1bd859e --- /dev/null +++ b/app/src/main/java/com/easyhz/picly/domain/model/album/IncomingImages.kt @@ -0,0 +1,8 @@ +package com.easyhz.picly.domain.model.album + +import android.net.Uri +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +class IncomingImages: ArrayList(), Parcelable diff --git a/app/src/main/java/com/easyhz/picly/domain/model/album/upload/gallery/GalleryImageItem.kt b/app/src/main/java/com/easyhz/picly/domain/model/album/upload/gallery/GalleryImageItem.kt index 09feac2..e4dc74e 100644 --- a/app/src/main/java/com/easyhz/picly/domain/model/album/upload/gallery/GalleryImageItem.kt +++ b/app/src/main/java/com/easyhz/picly/domain/model/album/upload/gallery/GalleryImageItem.kt @@ -19,7 +19,7 @@ data class GalleryImageItem( var position: Int = -1 ) { companion object { - fun Uri.toGalleryImageItem(context: Context): GalleryImageItem? { + suspend fun Uri.toGalleryImageItem(context: Context): GalleryImageItem? { val contentResolver = context.contentResolver val cursor = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { // Android 11 이상 contentResolver.query(this, null, null, null) diff --git a/app/src/main/java/com/easyhz/picly/provider/PiclyFileProvider.kt b/app/src/main/java/com/easyhz/picly/provider/PiclyFileProvider.kt new file mode 100644 index 0000000..2b1ab8f --- /dev/null +++ b/app/src/main/java/com/easyhz/picly/provider/PiclyFileProvider.kt @@ -0,0 +1,29 @@ +package com.easyhz.picly.provider + +import android.content.Context +import android.net.Uri +import androidx.core.content.FileProvider +import com.easyhz.picly.R +import com.easyhz.picly.util.saveImage +import java.io.File + +class PiclyFileProvider:FileProvider(R.xml.file_paths) { + companion object { + suspend fun getIncomingImageUri(context: Context, uri: Uri): Uri { + val directory = File(context.cacheDir, "images") + directory.mkdirs() + val file = File.createTempFile( + "incoming_image_", + ".jpeg", + directory, + ) + context.saveImage(uri, file) + val authority = context.packageName + ".fileprovider" + return getUriForFile( + context, + authority, + file, + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/easyhz/picly/util/Extensions.kt b/app/src/main/java/com/easyhz/picly/util/Extensions.kt index 93d66ac..0683b69 100644 --- a/app/src/main/java/com/easyhz/picly/util/Extensions.kt +++ b/app/src/main/java/com/easyhz/picly/util/Extensions.kt @@ -11,6 +11,10 @@ import com.easyhz.picly.data.entity.album.ImageSize import com.easyhz.picly.data.firebase.AuthError import com.easyhz.picly.domain.model.album.upload.gallery.GalleryImageItem import com.google.firebase.Timestamp +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import java.io.File +import java.io.FileOutputStream import java.time.Duration import java.time.LocalDateTime import java.time.ZoneId @@ -144,23 +148,54 @@ fun List.getImageUri(): List = /** - * 이미지 가로 세로를 가져 오는 함수 + * 이미지 가로 세로를 가져오는 함수 * * @return ImageSize */ -fun Context.getImageDimensions(uri: Uri): ImageSize { +suspend fun Context.getImageDimensions(uri: Uri): ImageSize = withContext(Dispatchers.IO) { contentResolver.openInputStream(uri)?.use { inputStream -> val options = BitmapFactory.Options().apply { inJustDecodeBounds = true } BitmapFactory.decodeStream(inputStream, null, options) - return ImageSize(height = options.outHeight.toLong(), width = options.outWidth.toLong(), ) - } - return ImageSize(938, 938) + return@withContext ImageSize(height = options.outHeight.toLong(), width = options.outWidth.toLong()) + } ?: return@withContext ImageSize(938, 938) } +/** + * 이미지 캐시 디렉토리에 저장하는 함수 + * + */ +suspend fun Context.saveImage(uri: Uri, cacheFile: File) { + withContext(Dispatchers.IO) { + try { + contentResolver.openInputStream(uri)?.use { inputStream -> + FileOutputStream(cacheFile).use { outputStream -> + inputStream.copyTo(outputStream, bufferSize = 1024) + } + } + } catch (e: Exception) { + throw e + } + } +} +suspend fun List.toGalleryImageItem(context: Context): List { + return map { + val imageSize = context.getImageDimensions(it) + GalleryImageItem( + id = it.hashCode().toLong(), + path = it.path ?: it.toString(), + uri = it, + name = it.toString(), + regDate = Timestamp.now().toDate().toString(), + size = 100, + width = imageSize.width, + height = imageSize.height + ) + } +} /** * 공유 url diff --git a/app/src/main/java/com/easyhz/picly/view/StartActivity.kt b/app/src/main/java/com/easyhz/picly/view/StartActivity.kt index 3e2c72f..9b3a679 100644 --- a/app/src/main/java/com/easyhz/picly/view/StartActivity.kt +++ b/app/src/main/java/com/easyhz/picly/view/StartActivity.kt @@ -1,6 +1,8 @@ package com.easyhz.picly.view import android.content.Intent +import android.net.Uri +import android.os.Build import android.os.Bundle import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity @@ -22,6 +24,7 @@ class StartActivity : AppCompatActivity() { super.onCreate(savedInstanceState) binding = ActivityStartBinding.inflate(layoutInflater) observeIsFirstRun() + handleIncomingImage() setContentView(binding.root) } @@ -40,7 +43,39 @@ class StartActivity : AppCompatActivity() { private fun startMainActivity(isFirstRun: Boolean) { val intent = Intent(this, MainActivity::class.java) intent.putExtra("isFirstRun" , isFirstRun) + intent.putParcelableArrayListExtra("incomingImages", handleIncomingImage().toCollection(ArrayList())) + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) startActivity(intent) finish() } + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + } + + /** + * Intent filter 로 들어온 사진을 처리 하는 함수 + */ + private fun handleIncomingImage(): List { + if (intent.type?.startsWith("image/") == false) return emptyList() + val imageUris = when(intent.action) { + Intent.ACTION_SEND -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + listOfNotNull(intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)) + } else { + @Suppress("DEPRECATION") + listOfNotNull(intent.getParcelableExtra(Intent.EXTRA_STREAM)) + } + } + Intent.ACTION_SEND_MULTIPLE -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)?.toList() + } else { + @Suppress("DEPRECATION") + intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM)?.toList() + } + } + else -> emptyList() + } ?: emptyList() + return imageUris + } } \ No newline at end of file diff --git a/app/src/main/java/com/easyhz/picly/view/album/upload/UploadFragment.kt b/app/src/main/java/com/easyhz/picly/view/album/upload/UploadFragment.kt index 6d6d1f9..c50cb87 100644 --- a/app/src/main/java/com/easyhz/picly/view/album/upload/UploadFragment.kt +++ b/app/src/main/java/com/easyhz/picly/view/album/upload/UploadFragment.kt @@ -24,12 +24,14 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider +import androidx.navigation.fragment.navArgs import androidx.recyclerview.widget.LinearLayoutManager import com.easyhz.picly.R import com.easyhz.picly.databinding.FragmentUploadBinding import com.easyhz.picly.domain.model.result.AlbumResult import com.easyhz.picly.domain.model.album.upload.gallery.GalleryImageItem import com.easyhz.picly.domain.model.album.upload.gallery.GalleryImageItem.Companion.toGalleryImageItem +import com.easyhz.picly.provider.PiclyFileProvider import com.easyhz.picly.util.BlueSnackBar import com.easyhz.picly.util.PICLY import com.easyhz.picly.util.animateGrow @@ -42,6 +44,7 @@ import com.easyhz.picly.util.getTime import com.easyhz.picly.util.getToday import com.easyhz.picly.util.showAlertDialog import com.easyhz.picly.util.toDateFormat +import com.easyhz.picly.util.toGalleryImageItem import com.easyhz.picly.util.toMs import com.easyhz.picly.util.toPx import com.easyhz.picly.util.toTimeFormat @@ -69,6 +72,7 @@ class UploadFragment: Fragment() { private var isShowCalendar: Boolean = false private var isShowTimePicker: Boolean = false private var isGranted: Boolean = false + private val args: UploadFragmentArgs by navArgs() // private val galleryPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> // this.isGranted = isGranted // } @@ -99,6 +103,7 @@ class UploadFragment: Fragment() { } private fun setUp() { + getIncomingImages() initCalendarView() initTimePicker() setTagField() @@ -116,6 +121,24 @@ class UploadFragment: Fragment() { setActivityResultLauncher() } + private fun getIncomingImages() { + loading.show(true) + CoroutineScope(Dispatchers.Main).launch { + try { + val incomingImages = args.incomingImages?.mapNotNull { + PiclyFileProvider.getIncomingImageUri(requireContext(), it) + } + incomingImages?.toGalleryImageItem(requireActivity())?.let { + viewModel.addSelectedImageList(it) + } + } catch (e: Exception) { + BlueSnackBar.make(binding.root, getString(R.string.incoming_image_error)) + } finally { + loading.show(false) + } + } + } + private fun initCalendarView() { binding.calendarView.visibility = View.INVISIBLE } @@ -234,14 +257,16 @@ class UploadFragment: Fragment() { BlueSnackBar.make(binding.root, getString(R.string.over_selected)).show() return@registerForActivityResult } - for (i in 0 until clipData.itemCount) { - val item = clipData.getItemAt(i).uri.toGalleryImageItem(requireActivity()) - item?.let { - selectedImages.add(it) + CoroutineScope(Dispatchers.Main).launch { + for (i in 0 until clipData.itemCount) { + val item = clipData.getItemAt(i).uri.toGalleryImageItem(requireActivity()) + item?.let { + selectedImages.add(it) + } } + viewModel.addSelectedImageList(selectedImages) } } - viewModel.addSelectedImageList(selectedImages) } } diff --git a/app/src/main/java/com/easyhz/picly/view/navigation/NavControllerManager.kt b/app/src/main/java/com/easyhz/picly/view/navigation/NavControllerManager.kt index cfa3923..fe560fe 100644 --- a/app/src/main/java/com/easyhz/picly/view/navigation/NavControllerManager.kt +++ b/app/src/main/java/com/easyhz/picly/view/navigation/NavControllerManager.kt @@ -5,6 +5,7 @@ import androidx.navigation.NavController import com.easyhz.picly.R import com.easyhz.picly.data.repository.user.UserManager import com.easyhz.picly.domain.model.album.AlbumItem +import com.easyhz.picly.domain.model.album.IncomingImages import com.easyhz.picly.view.MainFragmentDirections import com.easyhz.picly.view.album.detail.AlbumDetailFragmentDirections import com.easyhz.picly.view.album.upload.UploadFragmentDirections @@ -71,7 +72,12 @@ object NavControllerManager { } fun navigateMainToUpload() { - val action = MainFragmentDirections.actionMainFragmentToUploadFragment() + val action = MainFragmentDirections.actionMainFragmentToUploadFragment(null) + navControllerRef?.get()?.navigate(action) + } + + fun navigateMainToUploadWithIncoming(incomingImage: IncomingImages) { + val action = MainFragmentDirections.actionMainFragmentToUploadFragment(incomingImages = incomingImage) navControllerRef?.get()?.navigate(action) } diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index 4710080..fcaeaf1 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -12,7 +12,8 @@ > + app:destination="@id/uploadFragment" + /> @@ -133,6 +134,11 @@ android:label="UploadFragment" tools:layout="@layout/fragment_upload" > + @@ -140,6 +146,7 @@ android:id="@+id/action_uploadFragment_to_mainFragment" app:destination="@id/mainFragment" app:popUpTo="@id/mainFragment" + app:launchSingleTop="true" app:popUpToInclusive="true" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2e5c0bb..0768e9b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -146,4 +146,5 @@ 업로드한 앨범이 없습니다.\n +버튼을 눌러 앨범을 업로드하고 공유해보세요. + 이미지를 불러오는데 실패하였습니다. \ No newline at end of file diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml new file mode 100644 index 0000000..07a7eb1 --- /dev/null +++ b/app/src/main/res/xml/file_paths.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file