I want to load all the pictures from the media provider to my app by using MediaStore
API, but this column MediaStore.MediaColumns.DATA
is deprecated. So, what can I use as an alternative?
I want to update the following code to get rid of the deprecated MediaStore.MediaColumns.DATA
column:
fun ContentResolver.loadImagesPaths(): List<String> {
val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val images = mutableListOf<String>()
val projection = arrayOf(MediaStore.MediaColumns.DATA)
query(uri, projection, null, null, null)?.use { cursor ->
val dataColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA)
while (cursor.moveToNext()) {
images += cursor.getString(dataColumn)
}
}
return images
}
Edit:
Updated code:
fun ContentResolver.loadImagesUris(): List<Uri> {
val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val images = mutableListOf<Uri>()
val projection = arrayOf(MediaStore.Images.Media._ID)
query(uri, projection, null, null, null)?.use { cursor ->
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
while (cursor.moveToNext()) {
images += ContentUris.withAppendedId(uri, cursor.getLong(idColumn))
}
}
return images
}
Check out this link for further details on how to access media files from shared storage: https://developer.android.com/training/data-storage/shared/media
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.
// BUCKET_DISPLAY_NAME is a string like "Camera" which is the directory // name of where an image or video is in.
I was able to replace MediaStore.MediaColumns.Data with its own file ID (incredibly, files have IDs) and correctly constructing its URI, like this:
fun getAllShownImagesPath(activity: Activity): MutableList<Uri> {
val uriExternal: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val cursor: Cursor?
val columnIndexID: Int
val listOfAllImages: MutableList<Uri> = mutableListOf()
val projection = arrayOf(MediaStore.Images.Media._ID)
var imageId: Long
cursor = activity.contentResolver.query(uriExternal, projection, null, null, null)
if (cursor != null) {
columnIndexID = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
while (cursor.moveToNext()) {
imageId = cursor.getLong(columnIndexID)
val uriImage = Uri.withAppendedPath(uriExternal, "" + imageId)
listOfAllImages.add(uriImage)
}
cursor.close()
}
return listOfAllImages
}
and then with Uri you build it in your Views!
I managed to come up with the following solution, its kind of an addition to the previous answer
but there I still couldn't load images with the obtained Uri. Documentation suggested to use openFileDescriptor() which I did and then decoded images' bitmaps from it:
override fun loadImagesFromStorage(): List<AdapterImage> {
val uri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val cursor: Cursor?
val columnIndexId: Int
val listOfAllImages = mutableListOf<AdapterImage>()
val projection = arrayOf(MediaStore.Images.Media._ID)
cursor = context.contentResolver
.query( uri, projection, null, null, null)
if ( cursor != null ){
columnIndexId = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
while (cursor.moveToNext()){
val contentUri = ContentUris.withAppendedId(uri, cursor.getLong(columnIndexId))
//here I open FileDescriptor and then decode it into Bitmap
var image: Bitmap
context.contentResolver.openFileDescriptor(contentUri, "r").use { pfd ->
if( pfd != null ){
image = BitmapFactory.decodeFileDescriptor(pfd.fileDescriptor)
listOfAllImages.add(AdapterImage(image))
}
}
}
cursor.close()
}
return listOfAllImages
}
P.S. My method will return a list of AdapterImage objects that I use later in app but you can put anything you need there at this point
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With