8

For Android, the following code returns a Uri that can be used to create DocumentFile corresponding to a directory.

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, REQUEST_CODE_CUSTOM_FOLDER);

Since many methods of a library require a parameter to be java.io.File, I am wondering if one can get a java.io.File from a DocumentFile.

As an example, an returned document tree Uri treeUri is the following:

treeUri.getPath():/tree/primary:DCIM/deeper/evendeeper
treeUri.toString(): content://com.android.externalstorage.documents/tree/primary%3ADCIM%2Fdeeper%2Fevendeeper

The following is the directory shown in ADM: enter image description here

Hong
  • 17,643
  • 21
  • 81
  • 142

4 Answers4

4

the following code returns a Uri that can be used to create DocumentFile corresponding to a directory

No, it does not. It returns a Uri that can be used to create a DocumentFile corresponding to a tree of documents. There is no requirement for it to represent a directory on a filesystem. Where and how the document tree is represented is up to the DocumentsProvider that the user chose. That provider can do whatever it wants to represent the tree (e.g., use a database, use REST calls to a server).

I am wondering if one can get a java.io.File from a DocumentFile.

No, because there is no file.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks a lot for the prompt answer. Looks like we have to do the other way - changing the methods to use the inefficient DocumentFile instead of File. – Hong Sep 19 '16 at 16:32
1

Yes, but it may be that the address is in ASCII and you must convert it to UTF-8 to avoid text strings like "%2F". I recommend using "val decoded = URLDecoder.decode (input," utf-8 ")"

JMP M3dia
  • 24
  • 3
0

Yes, you can. For API 30+, you need full storage access. And for API 28-, you only need Manifest.permission.READ_EXTERNAL_STORAGE.

With SimpleStorage, you can convert DocumentFile to java.io.File:

val file: File? = documentFile.toRawFile(context)?.takeIf { it.canRead() }
Anggrayudi H
  • 14,977
  • 11
  • 54
  • 87
-3
I am wondering if one can get a java.io.File from a DocumentFile.

Yes mostly you can. If the user chooses a 'file' from primary or secondary storage you can as there is a one to one relationship between the content scheme and the file path of a file or directory.

But if you really need java.io.File you could better use a file picker.

[UPDATE]

content://com.android.externalstorage.documents/tree/primar%3ADCIM%2Fdeeper%2Fevendeeper 
content://com.android.externalstorage.documents/tree/primary:DCIM/deeper/evendeeper 

if that e.g. corresponds with

 /storage/emulated/0/DCIM/deeper/evendeeper. 

And

 content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fcom.aaaa.org%2Ffiles%2Fafile.txt
 content://com.android.externalstorage.documents/tree/primary:Android/com.aaaa.org/files/afile.txt

transforms in

/storage/emulated/0/Android/com.aaa.org/files/afil‌​e.txt

Then follows if you know one you know them all: there is a one to one relationship.

The only thing you have to do for conversion is replacing content://com.android.externalstorage.documents/tree/primary‌​: by /storage/emulated/0/

This reduces the problem to determining /storage/emulated/0/.

For that you once have to let the user choose the root of the file system path for the choosen content scheme. If it cannot be choosed that it often can be found with a file explorer app on the device. Finally you can let the path beeing typed in.

Precisely the opposite as done in Android SAF (Storage Access FrameWork): Get particular file Uri from TreeUri or in other posts with tag storage-acccess-framework.

Community
  • 1
  • 1
greenapps
  • 11,154
  • 2
  • 16
  • 19
  • 1
    Thanks for trying to help. How would you convert an instance of DocumentFile to java.io.File? – Hong Sep 19 '16 at 17:58
  • Please post the uri.toSting of a choosen document tree with the file system path of the same directory. Compare. – greenapps Sep 19 '16 at 18:05
  • 1
    Ok. But you did not post the corresponding file system path. I asked for that too. Something like /storage/emulated/0/DCIM or /sdcard/DCIM. – greenapps Sep 19 '16 at 20:51
  • Could you tell me how to get the file path from the Uri? – Hong Sep 19 '16 at 22:01
  • Wrong question. You should first answer my question. Repeat: What is the equivalent file system path of that DCIM directory? There are several posibilities to find out. You cannot use the uri for it. – greenapps Sep 19 '16 at 23:25
  • Is "storage/emulated/0/DCIM" what you are looking for? This is just an example. The directory could be any one that a user selects. The only thing that the app has is the Uri. Look forward to your further elucidation. – Hong Sep 19 '16 at 23:36
  • Ok. Then now pick a saf directory much deeper. And the corresponding files directory. Please post both. – greenapps Sep 20 '16 at 06:50
  • Sorry for my ignorance. I do not know how to get what you asked. Any tip will be appreciated. – Hong Sep 20 '16 at 11:25
  • What is the problem? You could pick that DCIM directory using ACTION_OPEN_DOCUMENT_TREE. Now can't you pick a different directory? Pick a directory some deeper in the tree. – greenapps Sep 20 '16 at 11:31
  • For better readability, I modified my original post by including an example of a deeper directory and an image showing the directory structure. I appreciate your persistent help. I assume we are heading in the direction of answering my original question about getting a java.io.File from a DocumentFile – Hong Sep 20 '16 at 12:21
  • You again did not post the corresponding file system directory with it. Dont post a picture. Post the file path. Dont use adb but use a file explorer app on your device to see the equivalent path. And you removed the DCIM choice. I did not ask you to create subdirectories in the DCIM directory. You could have choosen something in the Android directory as that goes pretty deep. Please post all paths for the DCIM directory and all paths for a dir that you choose deeper in that Android directory. – greenapps Sep 20 '16 at 12:27
  • So the corresponding path for the File class was /storage/emulated/0/DCIM/deeper/evendeeper. You should have pur that in your post. – greenapps Sep 20 '16 at 12:35
  • We can do it different. Please tell the corresponding file system path for content scheme `content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fcom.aaaa.org%2Ffiles%2Fafile.txt`. – greenapps Sep 20 '16 at 12:40
  • Very sorry for my ignorance. Could you offer a tip about how to get the file system path for content scheme content://com.android.externalstorage.documents/tree/primary‌​%3AAndroid%2Fcom.aaa‌​a.org%2Ffiles%2Fafil‌​e.txt? – Hong Sep 20 '16 at 12:49
  • If `content://com.android.externalstorage.documents/tree/primary%3ADCIM%2Fdeeper%2Fevendeeper` corresponds with `/storage/emulated/0/DCIM/deeper/evendeeper`. Than you should be able to tell the corresponding path for `content://com.android.externalstorage.documents/tree/primary‌​%3AAndroid%2Fcom.aaa‌​a.org%2Ffiles%2Fafil‌​e.txt`. – greenapps Sep 20 '16 at 12:59
  • Did you mean I should create the directory and the file exactly as you specified to find out this? Currently they do not exist. – Hong Sep 20 '16 at 14:36
  • Does not matter. No not create. Just tell the corresponding path. Determine the corresponding path. Tell the corresponding path. The corresponding path. – greenapps Sep 20 '16 at 23:33
  • How can I tell the corresponding path of something that does not exist. Again, please forgive my ignorance. – Hong Sep 20 '16 at 23:47
  • By looking at similarities. It is hard to believe that you do not see the similarities. And that you cannot tell the corresponding path for that content scheme. What does it matter that it does not exist on your device? Nothing! – greenapps Sep 20 '16 at 23:52
  • OK. I got it. You want me to write down what I think the path should be. Sorry for misunderstanding you. I am slow. Here it is what I think on what should be on this particular device: "storage/emulated/0/Android/com.a‌​aa‌​a.org/files/​afil‌​e.txt". The app is used by hundreds of thousands of users on probably hundreds, if not thousands, of different Android models. I do not know what this looks like on other models. Users have told us all kinds of weird directory structures. – Hong Sep 21 '16 at 01:38
  • Thanks a lot for the effort. I will have to test a few devices. It is an optional minor feature. It will be implemented only if it is simple and easy for the user too choose (e.g. via a dialog). – Hong Sep 22 '16 at 03:15