Android 11 - Scoped Storage - Unable To Use Even After Uri Permissions Are Granted

I'm currently migrating an Android app to Scoped Storage. Moving away from is a real nightmare, and feels much of a drawback to me. I'm currently trying to understand if paths returned by getExternalMediaDirs() can effectively be used with direct file paths.

After asking user to select a given folder

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uriToLoad);
startActivityForResult(intent, OPEN_DIRECTORY_REQUEST_CODE);

and storing persistent Uri permissions to read/write in onActivityResult

getContentResolver().takePersistableUriPermission(data.getData(), (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION));

Is it expected to still not being able to use in such granted path?

SAF path:


equivalent to path


Some final notes:

  • such path can be written with SAF
  • such path cannot be written with direct path (EACCES exception)
  • /Android/media/com.otherapp is different than self-attributed /Android/media/
  • android.permission.MANAGE_EXTERNAL_STORAGE not available

thanks nicola



Yes, because after granting permissions you have access to Content Scheme Uri of that specific folder not file system paths so you will be unable to list objects using this Uri.

But you can use it to listFiles() which will return you a list of DocumentFile. You can then use these DocumentFile objects to get Uri of that specific file using documentFile.getUri() . Using that Uri you can easily perform basic operations like display,copy,delete,share on that file.

Below is an example of listing files from a folder of other app.

I am skiping take permissions part of code assuming that you already have permissions to access that other app's folder

In this example i am listing files from Android/media/com.whatsapp/WhatsApp/Media/.Statuses

DOC Ids are

companion object {
    const val ANDROID_DOCID = "primary:Android/media/"
    private val androidUri = DocumentsContract.buildDocumentUri(
    val androidTreeUri = DocumentsContract.buildTreeDocumentUri(

After getting permission we have tree Uri

Here tree Uri is content://

val dir = DocumentFile.fromTreeUri(

This dir is a DocumentFile, now using this to list all folders inside that tree Uri.

val selectedPackageName = “com.whatsapp”
val FOLDER_NAME_STATUSES = ".Statuses”;
val selectedRootName = “WhatsApp"
var waStatus: DocumentFile? = null
val statusesFiles = arrayListOf<DocumentFile>()
dir?.listFiles()?.forEach {
    if ( {
        it.listFiles().forEach {
            if ( {
                it.listFiles().forEach {
                     if ( {
                                waStatus = it
                         statusesFiles.addAll(waStatus!!.listFiles().filter {
                                    it.mimeType.equals(Constants.MIME_TYPE_IMG_PNG) || it.mimeType.equals(
                                    ) || it.mimeType.equals(Constants.MIME_TYPE_IMG_JPEG)
                                }.sortedByDescending { it.lastModified() })




Now we have a list of DocumentFile from folder of another app. Use Uri of this file for further operations like display,copy,delete,share.

Also, read comments your point about Downloads folder but would this be the same matter for files in Download

Downloads is a public directory, i listed files which are created by my own app using listFiles() and it returned me list of File.

 val folder = File(
      if (folder != null && folder.exists()) {
                val newFiles: Array<File> = statusFolderInDownloads.listFiles({ file ->
                    getFileType(file.path) == FILETYPE.IMAGE || getFileType(file.path) == FILETYPE.VIDEO
                list.sortByDescending { it.lastModified() }
                if (list.isNotEmpty()) {
                    return list
                } else {
                    return arrayListOf()