Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 performed using MediaColumns#IS_PENDING, which offers richer control over lifecycle.

I don't really get it, since MediaColumns.IS_PENDING is just a flag, how am I supposed to use it?

Should I use ContentValues ?

like image 889
coroutineDispatcher Avatar asked Aug 30 '19 12:08

coroutineDispatcher


People also ask

Is MediaStore deprecated?

The filesystem and mediastore modules are deprecated. You should use the new storage module which is relying on Okio Filesystem API. On Android, every files on the shared storage (files visible when using a file manager) are indexed by MediaStore, to allow apps to query them by type, date, size, etc.

What is Android provider MediaStore?

↳ android.provider.MediaStore. The contract between the media provider and applications. Contains definitions for the supported URIs and columns. The media provider provides an indexed collection of common media types, such as Audio , Video , and Images , from any attached storage devices.


Video Answer


2 Answers

SOLVED

The code suggested from @CommonsWare has no problem, except the fact that if you are programming with targetSdkVersion 29, you must add the condition:

val contentValues = ContentValues().apply {             put(MediaStore.MediaColumns.DISPLAY_NAME, System.currentTimeMillis().toString())             put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { //this one                 put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation)                 put(MediaStore.MediaColumns.IS_PENDING, 1)             }         } 
like image 142
coroutineDispatcher Avatar answered Oct 13 '22 22:10

coroutineDispatcher


This method was deprecated in API level 29. inserting of images should be performed using MediaColumns#IS_PENDING, which offers richer control over the lifecycle.

Either I'm too stupid to understand the docs or the Google team really needs to refactor the documentation.

Anyways, posting the complete answer from the links provided by CommonsWare and coroutineDispatcher

Step 1: Decide on which API level you are

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) saveImageInQ(imageBitMap)     else saveImageInLegacy(imageBitMap) 

Step 2: Save the image in Q style

//Make sure to call this function on a worker thread, else it will block main thread fun saveImageInQ(bitmap: Bitmap):Uri {        val filename = "IMG_${System.currentTimeMillis()}.jpg"     var fos: OutputStream? = null     val imageUri: Uri? = null     val contentValues = ContentValues().apply {         put(MediaStore.MediaColumns.DISPLAY_NAME, filename)         put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg")         put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)         put(MediaStore.Video.Media.IS_PENDING, 1)     }      //use application context to get contentResolver     val contentResolver = application.contentResolver      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.JPEG, 70, it) }      contentValues.clear()     contentValues.put(MediaStore.Video.Media.IS_PENDING, 0)     resolver.update(imageUri, contentValues, null, null)                return imageUri } 

Step 3: If not on Q save the image in legacy style

//Make sure to call this function on a worker thread, else it will block main thread fun saveTheImageLegacyStyle(bitmap:Bitmap){     val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)     val image = File(imagesDir, filename)     fos = FileOutputStream(image)     fos?.use {bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)} } 

This should get you rolling!

like image 32
iCantC Avatar answered Oct 13 '22 23:10

iCantC