Context:
Simple file explorer which shows a folder contents and allow user open any file with another app depending of the mime type
The expected behavior:
- Click in a button that launch
OPEN_DOCUMENT_TREE
activity - User select a folder A
- Display all folder A contents in a list view
- When user click in a list item, launch
ACTION_VIEW
to open the file document inside another app that support rendering the contents
What I got actually:
- In the last step, the
SecurityException
is being thrown
The generation of my intent looks like:
fun someOfGrantedUris(): Uri {
// These Uris were returned by `ACTION_OPEN_DOCUMENT_TREE` activity
val grantedUris = contentResolver.persistedUriPermissions
return grantedUris[0] // Consider this a Uri always not null and valid
}
val parentDocument = DocumentFile.fromTreeUri(someOfGrantedUris())
val childDocument = parentDocument.listFiles()[0] // First child document
val uri = childDocument.uri
val intent =
Intent(Intent.ACTION_VIEW).apply {
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addCategory(Intent.CATEGORY_DEFAULT)
// This is the same of just `uriWithProviderScheme = uri`
// but in this way I can change any part of the Uri to test and debug
val uriWithProviderScheme = Uri.Builder().let {
it.scheme(uri.scheme)
it.path(uri.path)
it.query(uri.query)
it.authority(uri.authority)
it.build()
}
setDataAndType(uriWithProviderScheme, type)
}
But when I try to start this activity:
try {
// This is not native Android but a Flutter plugin
plugin.binding?.activity?.startActivity(intent, null)
} catch (e: SecurityException) {
// I always fall here
}
I have all runtime permissions already granted:
READ_EXTERNAL_STORAGE
andWRITE_EXTERNAL_STORAGE
I can also delete the child document by using
childDocument.delete()
it works fine, but when I try to launch it onACTION_VIEW
a SecurityException is thrown, why?
class java.lang.SecurityException: UID 10498 does not have permission to content://com.android.externalstorage.documents/tree/primary%3ADownload/offline/document/primary%3ADownload/offline/Sample%20File.txt [user 0]; you could obtain access using ACTION_OPEN_DOCUMENT or related APIs
Even though we can try to use ACTION_OPEN_DOCUMENT
this is not what I'm looking for since I already requested permissions before with ACTION_OPEN_DOCUMENT_TREE
and by the docs:
Grant access to a directory's contents: The
ACTION_OPEN_DOCUMENT_TREE
intent action, available on Android 5.0 (API level 21) and higher, allows users to select a specific directory, granting your app access to all of the files and sub-directories within that directory.