0

I am new to android development and trying to build a WhatsApp status saver app. For SDK level 29 and above we need content resolver to access the files in a specific folder.

Here is my childDocumentUri Uri to pass into contentResolver.query(..) method:

val wa_status_uri = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fmedia/document/primary%3AAndroid%2Fmedia%2Fcom.whatsapp%2FWhatsApp%2FMedia%2F.Statuses")

val childDocumentUri = DocumentsContract.buildChildDocumentsUriUsingTree(wa_status_uri, DocumentsContract.getDocumentId(wa_status_uri))

This is how I'm trying to access all the files:-

fun getImageStatuses(childDocumentUri: Uri): MutableList<Status>{
        val projection = arrayOf(
            MediaStore.Files.FileColumns._ID,
            MediaStore.Files.FileColumns.DISPLAY_NAME,
            MediaStore.Files.FileColumns.MIME_TYPE
        )

        val selection = "${MediaStore.Files.FileColumns.MEDIA_TYPE} LIKE ?"
        val selectionArgs = arrayOf("image/jpeg")

        val statusMutableList = mutableListOf<Status>()
        contentResolver.query(
            childDocumentUri,
            projection,
            selection,
            selectionArgs,
            "${MediaStore.Files.FileColumns.DATE_ADDED} DESC"
        )?.use { cursor ->

            val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID)
            val nameColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME)
            val mimeColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE)

            while (cursor.moveToNext()) {
                val id = cursor.getLong(idColumn)
                val displayName = cursor.getString(nameColumn)
                val mimeType = cursor.getString(mimeColumn)
                val contentUri = ContentUris.withAppendedId(
                    collection,
                    id
                )

                if (selectionArgs == null || mimeType == selectionArgs[0]) {
                    statusMutableList.add(Status(id, displayName, contentUri))
                }

            }
            statusMutableList
        } ?: mutableListOf()

        return statusMutableList
}

The problem is that instead of returning just jpg file because of selection and selectionArgs, cursor is returning mp4 files also and I've to explicitly filter images like this:-

if (selectionArgs == null || mimeType == selectionArgs[0]) {
                    statusMutableList.add(Status(id, displayName, contentUri))
                }

I've already taken persistable uri permission as shown in this answer but it's only for sdk level 29 and up. How can I do the same for sdk level 28 and below. Can I even use this contentResolver.query(..) method in sdk level 28 and below. If yes, then what will be my collection Uri and how will I take persistable permission for WhatsApp folder located as: Android/WhatsApp/

  • `we need content resolver to access the files in a specific folder.` I dont know what you have in mind but never heard this before. – blackapps Mar 09 '23 at 18:09
  • `This is how I'm trying to access all the files:-` That code is accessing nothing. It looks as if you try to make a list. – blackapps Mar 09 '23 at 18:11
  • `getImageStatuses(collection: Uri): ` It is unclear what you use as collection. Start your code with the collection and then call that function with it. Show what you do! – blackapps Mar 09 '23 at 18:14
  • `val collection = DocumentsContract.buildChildDocumentsUriUsingTree(wa_status_uri, DocumentsContract.getDocumentId(wa_status_uri))` Why are you calling a childdocumentsuri a collection? Pretty confusing. – blackapps Mar 09 '23 at 18:19
  • I've edited my code to make it bit more readable. – Perfect One Mar 10 '23 at 05:03
  • `This is how I'm trying to access all the files:-` is the code which returns me the list of `ID, DISPLAY_NAME and contentUri` of the items inside Statuses folder – Perfect One Mar 10 '23 at 05:05
  • ` I dont know what you have in mind but never heard this before.` I got the idea to do it like this from [this answer](https://stackoverflow.com/a/68408220/21365448) – Perfect One Mar 10 '23 at 05:11
  • You still are not showing how you call getImageStatuses(). Please make clear what you do. And if you do it like i think you do the caal it like getImageStatuses(wa_status_uri) and move the childrenuri line to in in that function as there it is where you wanna use a children uri. You need that children uri to make a listing for the folder uri. – blackapps Mar 10 '23 at 08:21

1 Answers1

0

val selection = "${MediaStore.Files.FileColumns.MEDIA_TYPE} LIKE ?"

val selection = "${MediaStore.Files.FileColumns.MIME_TYPE} LIKE ?"
blackapps
  • 8,011
  • 2
  • 11
  • 25