I'm requesting a directory tree from a user and I want to read all files. I'm then using something similar to this to traverse all the files. I want to then read the files (specifically create InputStreams). I tried to find a way to use COLUMN_DOCUMENT_ID and the various open file methods but they either require Uri or filepath and I can't find a way to get one from the document id. I found this method which seems like it would work for me, but it's on an abstract class and I couldn't find an implementation for the android file system. Is there a standard way to do this? I'm probably missing something obvious.
Asked
Active
Viewed 409 times
1
-
From your linked-to question, [this answer](https://stackoverflow.com/a/49300404/115145) would seem to be what you are looking for. Given that `Uri`, use a `ContentResolver` and `openInputStream()` to get an `InputStream` on the content. – CommonsWare Oct 05 '19 at 20:38
-
1Doesn't this create uri pointing to all children? How would I go about opening each of them? As I understand it I couldn't pass a file id there, because it requires the id to be a directory id. – mdatsev Oct 05 '19 at 20:44
-
1Oh, sorry, you're right. I was not paying close enough attention. [`buildDocumentUri()`](https://developer.android.com/reference/android/provider/DocumentsContract.html#buildDocumentUri(java.lang.String,%20java.lang.String)) is the method that you want, AFAIK. – CommonsWare Oct 05 '19 at 20:51
-
In the code for the listing you see final Uri newNode = DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, docId); . You can use that uri to tet the content resolver open an input stream. – blackapps Oct 06 '19 at 09:25
1 Answers
1
I ran into this and worked out the following way of doing it.
buildDocumentUriUsingTree() does this.
When the user chooses a directory, with SAF storage picker, the URI for that directory is returned in onActivityResult. You will need to take persistable permission on that URI, like this:
getContentResolver().takePersistableUriPermission(theSafReturnedTreeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
You can store the String returned by theSafReturnedTreeUri.toString() in order to reconstruct that URI anytime using:
Uri.parse(Uri.decode(theString));
When you want to access a file under that directory, use buildDocumentUriUsingTree, passing it theSafReturnedTreeUri and the Document ID returned when using ContentResolver to query for COLUMN_DOCUMENT_ID.
Uri myFileUri = DocumentsContract.buildDocumentUriUsingTree(theSafReturnedTreeUri, theDocIdQueriedForWithContentResolver);
That gives you a working URI for the file that you should be able to use with ContentResolver.openInputStream.

Pizza and Coke
- 103
- 1
- 8