Search code examples
androidfileandroid-permissionsandroid-fileprovider

Using `FileProvider.getUriForFile` in Android 30 for public folder throws `Failed to find configured root`


I'm using the following code to save a file to public download folder.

val resolver = this.contentResolver
val contentValues = ContentValues().apply {
    put(MediaStore.Files.FileColumns.DISPLAY_NAME, "$fileName.pdf")
    put(MediaStore.Files.FileColumns.MIME_TYPE, "application/pdf")
    put(
        MediaStore.Files.FileColumns.RELATIVE_PATH,
        Environment.DIRECTORY_DOWNLOADS
        )
    }
val uri = resolver.insert(
                          MediaStore.Downloads.EXTERNAL_CONTENT_URI,
                          contentValues
                  )

val fos = this.contentResolver.openOutputStream(uri!!)
fos?.write(fileContent)
fos?.flush()
fos?.close()
val uriString = uri.toString()
return uriString

I'm trying to show a notification to user and add an Intent to open the downloaded file. I use the uriString passed from the save document code.

var uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", File(uriString))
val intent = Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/pdf")

This code works fine till Android Pie. But fails on Android 30 with following exception.

Failed to handle method call
    java.lang.IllegalArgumentException: Failed to find configured root that contains /content:/media/external/downloads/36
        at androidx.core.content.FileProvider$SimplePathStrategy.getUriForFile

Solution

  • Dont try to build up a new uri if you have already one.

    No need to use FileProvider.

    Use val uri as that is the uri to the file.

    Put as extra a read flag on the used intent.