개발/안드로이드

MediaStore.Images.Media.insertImage deprecated

스몰스테핑 2024. 6. 10. 16:45

https://small-stepping.tistory.com/1005

 

WorkManager로 백그라운드 작업

WorkManager란?WorkManager는 상황별 실행과 보장된 실행을 조합하여 적용해야 하는 백그라운드 작업을 위한 아키텍처 구성요소로서 Android Jetpack의 일부이다. 상황별 실행을 적용하면 WorkManager가 최대

small-stepping.tistory.com

 

위 공부를 할 때, 따라한 Jetpack Compose Tutorial 프로젝트에서 사용한 이미지를 저장하는 파트에서 Media.insertImage를 사용하는 부분이 존재했는데, 해당 부분이 API 레벨 29에서부터 deprecated 되어 수정이 필요했다.

 

https://stackoverflow.com/questions/57726896/mediastore-images-media-insertimage-deprecated

 

MediaStore.Images.Media.insertImage deprecated

I used to save images using MediaStore.Images.Media.insertImage but insertImage method is now deprecated. The docs say: This method was deprecated in API level 29. inserting of images should be

stackoverflow.com

 

검색을 통해 contentValues를 사용하고, OutputStream을 사용해야한다는 것을 알게 되었다.

 

 

전체 코드

return withContext(Dispatchers.IO) {
    val contentResolver = applicationContext.contentResolver
    return@withContext try {
        val resourceUri = inputData.getString(KEY_IMAGE_URI)
        val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(Uri.parse(resourceUri)))
        val imageUri: Uri?
        val fos: OutputStream?

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val contentValues = ContentValues().apply {
                put(MediaStore.MediaColumns.DISPLAY_NAME, title)
                put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
                put(MediaStore.MediaColumns.DATE_ADDED, dateFormatter.format(Date()))
                put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
                put(MediaStore.Video.Media.IS_PENDING, 1)
            }

            contentResolver.also { resolver ->
                imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
                fos = imageUri?.let { resolver.openOutputStream(it) }
            }
            fos?.use { bitmap.compress(Bitmap.CompressFormat.PNG, 100, it) }

            contentValues.clear()
            contentValues.put(MediaStore.Video.Media.IS_PENDING, 0)
            contentResolver.update(Uri.parse(resourceUri), contentValues, null, null)
        } else {
            val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
            val image = File(imagesDir, title)

            fos = FileOutputStream(image)
            fos.use { bitmap.compress(Bitmap.CompressFormat.PNG, 100, it) }
        }

        Result.success()
    } catch (exception: Exception) {
        Result.failure()
    }
}

 

사용자의 기기 빌드 버전을 체크하여 작업을 다르게 사용한다.

 

 

공통적으로 필요한 것

val resourceUri = null
val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(Uri.parse(resourceUri)))
val imageUri: Uri?
val fos: OutputStream?

 

 

Q 빌드 버전으로 이미지를 저장할 경우

val contentValues = ContentValues().apply {
    put(MediaStore.MediaColumns.DISPLAY_NAME, title)
    put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
    put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
    put(MediaStore.Video.Media.IS_PENDING, 1)
}

contentResolver.also { resolver ->
    imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
    fos = imageUri?.let { resolver.openOutputStream(it) }
}
fos?.use { bitmap.compress(Bitmap.CompressFormat.PNG, 100, it) }

contentValues.clear()
contentValues.put(MediaStore.Video.Media.IS_PENDING, 0)
contentResolver.update(Uri.parse(resourceUri), contentValues, null, null)

 

 

 

레거시 스타일로 이미지를 저장할 경우

val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
val image = File(imagesDir, title)

fos = FileOutputStream(image)
fos.use { bitmap.compress(Bitmap.CompressFormat.PNG, 100, it) }

 

위 작업에서 PNG, JPG, WEPG 방식으로 저장이 가능하다.