'MediaStore can't list all of videos inside the phone in Kotlin. Why?

I created a function to fetch videos

private val projectionVideo = arrayOf(
MediaStore.Video.Media._ID, //ID
MediaStore.Video.Media.DISPLAY_NAME, //NAME
MediaStore.Video.Media.DATA, //PATH TO CONTENT
MediaStore.Video.Media.DATE_TAKEN, //DATE
MediaStore.Video.Media.DURATION,
MediaStore.Video.Media.SIZE
)

private fun queryVideos(cr: ContentResolver): Cursor? =
        cr.query(
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
            projectionVideo, null, null,
            MediaStore.Video.Media.DATE_TAKEN + " $SORT_ORDER"
        )

In Java

public static Uri getContentUri(String volumeName) {
                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
                        "/video/media");
            }
            /**
             * The content:// style URI for the internal storage.
             */
            public static final Uri INTERNAL_CONTENT_URI =
                    getContentUri("internal");
            /**
             * The content:// style URI for the "primary" external storage
             * volume.
             */
            public static final Uri EXTERNAL_CONTENT_URI =
                    getContentUri("external");

The issue is this one not showing up any videos in any paths, like 'DCIM', 'WhatsApp Videos' etc. Every video I create with my own app will be correctly inserted, unlike the ones created by the default camera app, unless I open them first.



Solution 1:[1]

You can read all videos from Android Shared Storage with this code

    private val videoProjection = arrayOf(
               MediaStore.Video.Media._ID,
               MediaStore.Video.Media.DATA,
               MediaStore.Video.Media.DURATION,
               MediaStore.Video.Media.MIME_TYPE,
               MediaStore.Video.Media.SIZE,
               MediaStore.Video.Media.DATE_ADDED)


    context.contentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
            videoProjection,
            null,
            null,
            "${MediaStore.Video.Media.DATE_ADDED} DESC"
    )?.use { cursor ->
        while (cursor.moveToNext()) {
           //read video attr from cursor
           cursor.getLong(cursor.getColumnIndexOrThrow(videoProjection[0])) // read video id 
           cursor.getString(cursor.getColumnIndexOrThrow(videoProjection[1])) // read video path 
           // and .....
        }
    }

Solution 2:[2]

fun getAllVideos(): ArrayList<FileGallery>? {
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            var columnVideo:Int ?= null
            var columnFolder:Int ?= null
            var columnDateAdded:Int ?= null

            var absolutePathVideo:String ?= null
            var folderName:String ?= null
            var dateAdded:String ?= null

            val uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
            val projection = arrayOf(
                MediaStore.Video.Media.DATA,
                MediaStore.Video.VideoColumns.DATE_ADDED,
                MediaStore.Video.Media.BUCKET_DISPLAY_NAME
            )

            val orderBy:String = MediaStore.Video.Media.DATE_TAKEN

            val cursor = context.contentResolver.query(
                uri,
                projection,
                null,
                null,
                "$orderBy DESC"
            )

            var listVideo = arrayListOf<FileGallery>()

            columnVideo = cursor?.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)
            columnFolder = cursor?.getColumnIndexOrThrow(MediaStore.Video.Media.BUCKET_DISPLAY_NAME)
            columnDateAdded = cursor?.getColumnIndexOrThrow(MediaStore.Video.VideoColumns.DATE_ADDED)

            while (cursor?.moveToNext() == true){
                absolutePathVideo = cursor.getString(columnVideo!!)
                folderName = cursor.getString(columnFolder!!)
                dateAdded = cursor.getString(columnDateAdded!!)
                listVideo.add(FileGallery(absolutePathVideo, folderName, dateAdded))
            }
            return listVideo
        }else{
            return null
        }
    }catch (e:Exception){
        Log.e("ERROR", e.message?:"")
        return null
    }
}

try this

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mehdi Yari
Solution 2 Taufik Fadlurahman Fajari