Dialog Plugin pick_folder not implemented
Hello, I've been trying to open a folder selection dialog via the dialog plugin on Android. The Folder selection works no problem on Desktop, but the compiler is unable to find the "pick_folder" method once i try to compile to android. "pick_file" on the other hand seems to work just fine.
Is there a reason "pick_folder" is not implemented for android?
tauri ="2.0.0-beta" tauri-plugin-dialog = "2.0.0-beta"
I also encountered this problem, have you solved it?
+1 really would like this feature as well I'm also curious as to why it was the only one not added yet
+1
Is anyone working on this?
I don't think so(
I wrote an android folder picker implementation for the dialog plugin here. However, the folder picker returns a content:// URI instead of the actual filesystem path, and these content URI's are not yet supported by the FS plugin (only file:// URI's are supported if I understand correctly). We can, however, convert the URI to an actual filesystem path like this:
if (DocumentsContract.isTreeUri(uri)) {
val docId = DocumentsContract.getTreeDocumentId(uri)
val split = docId.split(":")
return if (split.size > 1 && "primary".equals(split[0], ignoreCase = true)) {
"${Environment.getExternalStorageDirectory()}/${split[1]}"
} else {
null
}
}
This path can be used by the FS plugin. But I'm not sure if this is an acceptable approach. If we want to use the content:// URI's as android intends them to be used, the FS plugin will need a couple of changes.
The fs plugin supports content:// urls. We get those from the file picker as well. But you're probably still correct, i'd assume it needs changes to support content:// urls for directories as well.
Implementing a directory picker for Android comes with one major challenge: handling the URIs that represent directories. After outlining the problem, I would like to present the two solutions I am currently considering. I would appreciate feedback on which approach seems preferable, as well as any alternative ideas or possible improvements.
Note: I am using a translation tool, so please excuse any awkward expressions.
Problem
The current Tauri file-system path type, tauri_plugin_fs::FilePath, can store only a single path or URI (file:// or content://).
However, directory URIs on Android require multiple related URIs to be stored together, which leads to a mismatch with the existing design.
There are three primary URIs involved in representing a directory:
-
Tree URI
The URI returned by the directory picker. -
Document URI
A URI that provides metadata about an entry (e.g., its name, size, or file descriptor). -
Child Document URI
A URI that is valid only when the entry is a directory and is used to retrieve its child files or subdirectories.
Both a Document URI and a Child Document URI can be constructed from a Tree URI.
However, when obtaining entries through operations such as readDir or mkdir, the Tree URI cannot be retrieved; only the other two URIs are available.
Furthermore, these two URIs cannot be used to reconstruct each other or the original Tree URI.
Therefore, Tauri’s current tauri_plugin_fs::FsPath, which can hold only a single URI, is unable to correctly represent directory URIs on Android.
Solution
There are two possible solutions to this problem.
Adding DirectoryHandle and openDir
The directory picker in the dialog plugin would return a Tree URI.
Then, the fs plugin’s openDir function would accept that Tree URI and return a DirectoryHandle.
A DirectoryHandle would provide methods such as DirectoryHandle.readDir and mkdir, but it would not expose any directory URIs.
Instead, all URIs would be kept internal and abstracted away.
For this reason, operations like readDir would return another DirectoryHandle rather than a raw URI.
This approach is necessary because, as explained earlier, entries under a Tree URI cannot be fully represented using a single URI.
Add custom FS URI
The second solution is to define a Custom FS URI that embeds arbitrary data—such as a Document URI and a Child Document URI—directly within the URI string itself.
This makes it possible to represent a directory using a single URI.
The advantage of this approach is that it does not require introducing new concepts such as openDir or DirectoryHandle.
All that’s needed is to extend the existing readDir return value to include a simple { path: string }.
Additionally, we introduce a new ContentProvider, which is the component commonly used in the Android file system to handle content:// URIs of Custom fs URI.
This provider would accept the Custom FS URI, extract the underlying Document URI, and perform transparent operations using it.
In other words, Tauri maintainers and plugin developers can continue to obtain metadata (such as file or directory names) and file descriptors using the same APIs as before.
No changes to existing code are required.
Only directory-listing operations need special handling to process the embedded data.
I’d really like to hear everyone’s thoughts. Thank you :>
Implementing a directory picker for Android comes with one major challenge: handling the URIs that represent directories. After outlining the problem, I would like to present the two solutions I am currently considering. I would appreciate feedback on which approach seems preferable, as well as any alternative ideas or possible improvements.
Note: I am using a translation tool, so please excuse any awkward expressions.
Problem
The current Tauri file-system path type,
tauri_plugin_fs::FilePath, can store only a single path or URI (file://orcontent://). However, directory URIs on Android require multiple related URIs to be stored together, which leads to a mismatch with the existing design.There are three primary URIs involved in representing a directory:
1. **Tree URI** The URI returned by the directory picker. 2. **Document URI** A URI that provides metadata about an entry (e.g., its name, size, or file descriptor). 3. **Child Document URI** A URI that is valid only when the entry is a directory and is used to retrieve its child files or subdirectories.
Both a Document URI and a Child Document URI can be constructed from a Tree URI. However, when obtaining entries through operations such as
readDirormkdir, the Tree URI cannot be retrieved; only the other two URIs are available. Furthermore, these two URIs cannot be used to reconstruct each other or the original Tree URI.Therefore, Tauri’s current
tauri_plugin_fs::FsPath, which can hold only a single URI, is unable to correctly represent directory URIs on Android.Solution
There are two possible solutions to this problem.
Adding
DirectoryHandleandopenDirThe directory picker in the dialog plugin would return a Tree URI. Then, the
fsplugin’sopenDirfunction would accept that Tree URI and return aDirectoryHandle.A
DirectoryHandlewould provide methods such asDirectoryHandle.readDirandmkdir, but it would not expose any directory URIs. Instead, all URIs would be kept internal and abstracted away. For this reason, operations likereadDirwould return anotherDirectoryHandlerather than a raw URI.This approach is necessary because, as explained earlier, entries under a Tree URI cannot be fully represented using a single URI.
Add custom FS URI
The second solution is to define a Custom FS URI that embeds arbitrary data—such as a Document URI and a Child Document URI—directly within the URI string itself. This makes it possible to represent a directory using a single URI.
The advantage of this approach is that it does not require introducing new concepts such as
openDirorDirectoryHandle. All that’s needed is to extend the existingreadDirreturn value to include a simple{ path: string }.Additionally, we introduce a new
ContentProvider, which is the component commonly used in the Android file system to handlecontent://URIs of Custom fs URI. This provider would accept the Custom FS URI, extract the underlying Document URI, and perform transparent operations using it.In other words, Tauri maintainers and plugin developers can continue to obtain metadata (such as file or directory names) and file descriptors using the same APIs as before. No changes to existing code are required. Only directory-listing operations need special handling to process the embedded data.
I’d really like to hear everyone’s thoughts. Thank you :>
I'm very interested in your second solution, since it'll be compatible with previous usage of the filesystem plugin. I've made a quick prototype to test it out and for my usecase this seems to be working great! It's almost fully compatible with my previous codebase. Only thing I couldn't get working for now is file watching using a ContentObserver, so I've settled for a polling-based approach in the prototype. I'm just leaving this here for if anyone wants to continue exploring the approach. Great idea!
Thank you. If anything, I also currently find the second option preferable, since it requires fewer surface-level changes and additions. However, I’m concerned that introducing custom URIs might add complexity, which could make maintaining Tauri even more difficult.
Does anyone know which approach is generally preferred in the context of Tauri?