Background
There are various storage restrictions on Android 10 and 11, which also includes a new permission (MANAGE_EXTERNAL_STORAGE) to access all files (yet it doesn't allow access to really all files ) while the previous storage permission got reduced to grant access just to media files :
- Apps can reach the "media" sub folder freely.
- Apps can never reach "data" sub folder and especially the content.
- For "obb" folder, if the app was allowed to install apps, it can reach it (to copy files to there). Otherwise it can't.
- Using USB or root, you could still reach them, and as an end user you can reach them via the built-in file-manager app "Files".
The problem
I've noticed an app that somehow overcome this limitation (here) called "X-plore": Once you enter "Android/data" folder, it asks you to grant access to it (directly using SAF, somehow), and when you grant it, you can access everything in all folders of "Android" folder.
This means there might still be a way to reach it, but problem is that I couldn't make a sample that does the same, for some reason.
What I've found and tried
It seems this app targets API 29 (Android 10), and that it doesn't use the new permission yet, and that it has the flag requestLegacyExternalStorage. I don't know if the same trick they use will work when targeting API 30, but I can say that on my case, running on Pixel 4 with Android 11, it works fine.
So I tried to do the same:
-
I made a sample POC that targets Android API 29, has storage permissions (of all kinds) granted, including the legacy flag.
-
I tried to request access directly to "Android" folder (based on here), which sadly didn't work as it goes to some reason (kept going to DCIM folder, no idea why) :
val androidFolderDocumentFile = DocumentFile.fromFile(File(primaryVolume.directory!!, "Android"))
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
.putExtra(DocumentsContract.EXTRA_INITIAL_URI, androidFolderDocumentFile.uri)
startActivityForResult(intent, 1)
I tried various flags combinations.
-
When launching the app, when I reach the "Android" folder myself manually as this didn't work well, and I granted the access to this folder just like on the other app.
-
When getting the result, I try to fetch the files and folders in the path, but it fails to get them:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
Log.d("AppLog", "resultCode:$resultCode")
val uri = data?.data ?: return
if (!DocumentFile.isDocumentUri(this, uri))
return
val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
contentResolver.takePersistableUriPermission(uri, takeFlags)
val fullPathFromTreeUri = FileUtilEx.getFullPathFromTreeUri(this, uri) // code for this here: https://stackoverflow.com/q/56657639/878126
val documentFile = DocumentFile.fromTreeUri(this, uri)
val listFiles: Array<DocumentFile> = documentFile!!.listFiles() // this returns just an array of a single folder ("media")
val androidFolder = File(fullPathFromTreeUri)
androidFolder.listFiles()?.forEach {
Log.d("AppLog", "${it.absoluteFile} children:${it.listFiles()?.joinToString()}") //this does find the folders, but can't reach their contents
}
Log.d("AppLog", "granted uri:$uri $fullPathFromTreeUri")
}
So using DocumentFile.fromTreeUri I could still get just "media" folder which is useless, and using the File class I could only see there are also "data" and "obb" folders, but still couldn't reach their contents...
So this didn't work well at all.
Later I've found out another app that uses this trick, called "MiXplorer". On this app, it failed to request "Android" folder directly (maybe it didn't even try), but it does grant you full access to it and its sub-folders once you allow it. And, it targets API 30, so this means it's not working just because you target API 29.
The questions
- How can I request an Intent directly to "Android" folder?
- How can I get the contents of the sub-folders?
- Is there another alternative for this? Maybe using adb and/or root, I could grant SAF access to this specific folder ?
from How do some apps reach the contents of ".../Android/..." sub-folders on Android 11 without root?
No comments:
Post a Comment