AndroidFs

Struct AndroidFs 

Source
pub struct AndroidFs<R: Runtime> { /* private fields */ }
Expand description

Root API

§Examples

fn example(app: &tauri::AppHandle) {
    use tauri_plugin_android_fs::AndroidFsExt as _;
 
    let api = app.android_fs();
}

Implementations§

Source§

impl<R: Runtime> AndroidFs<R>

Source

pub fn private_storage(&self) -> PrivateStorage<'_, R>

API of file storage intended for the app’s use only.

Source

pub fn public_storage(&self) -> PublicStorage<'_, R>

API of file storage that is available to other applications and users.

Source

pub fn file_picker(&self) -> FilePicker<'_, R>

API of file/dir picker.

Source

pub fn file_sender(&self) -> FileSender<'_, R>

API of sharing files with other apps.

Source

pub fn get_name(&self, uri: &FileUri) -> Result<String>

Get the file or directory name.

§Args
  • uri :
    Target URI.
    Must be readable.
§Support

All.

Source

pub fn get_mime_type(&self, uri: &FileUri) -> Result<String>

Queries the provider to get the MIME type.

For files in PrivateStorage, the MIME type is determined from the file extension.
In most other cases, it uses the MIME type that was associated with the file when it was created.
If the MIME type is unknown or unset, it falls back to "application/octet-stream".

If the target is a directory, an error will occur.
To check whether the target is a file or a directory, use AndroidFs::get_type.

§Args
  • uri :
    Target file URI.
    Must be readable.
§Support

All.

Source

pub fn get_type(&self, uri: &FileUri) -> Result<EntryType>

Gets the entry type.

If the target is a directory, returns EntryType::Dir.

If the target is a file, returns EntryType::File { mime_type }.
For files in PrivateStorage, the MIME type is determined from the file extension.
In most other cases, it uses the MIME type that was associated with the file when it was created.
If the MIME type is unknown or unset, it falls back to "application/octet-stream".

§Args
  • uri :
    Target URI.
    Must be readable.
§Support

All.

Source

pub fn get_metadata(&self, uri: &FileUri) -> Result<Metadata>

Queries the file system to get information about a file, directory.

§Args
  • uri :
    Target URI.
    Must be readable.
§Note

This uses AndroidFs::open_file internally.

§Support

All.

Source

pub fn open_file_readable(&self, uri: &FileUri) -> Result<File>

Open the file in readable mode.

§Note

If the target is a file on cloud storage or otherwise not physically present on the device, the system creates a temporary file, downloads the data into it, and then opens it. As a result, this processing may take longer than with regular local files.

§Args
  • uri :
    Target file URI.
    This need to be readable.
§Support

All.

Source

pub fn open_file_writable(&self, uri: &FileUri) -> Result<File>

Open the file in writable mode.
This truncates the existing contents.

If you only need a std::io::Write instead of a std::fs::File, or if applicable, please use AndroidFs::open_writable_stream instead.

§Note

If the target is a file on cloud storage or otherwise not actually present on the device, writing with such files may not correctly reflect the changes.
In this case, this function may causes an error, or may not.
If you need write with such files, use AndroidFs::open_writable_stream.

§Args
  • uri :
    Target file URI.
    This need to be writable.
§Support

All.

Source

pub fn open_file(&self, uri: &FileUri, mode: FileAccessMode) -> Result<File>

Open the file in the specified mode.

§Note

If the target is a file on cloud storage or otherwise not physically present on the device, the system creates a temporary file, downloads the data into it, and then opens it. As a result, this processing may take longer than with regular local files.

When writing to a file with this function, pay attention to the following points:

  1. Files that do not exist on the device:
    Writing to files that are not physically present on the device may not correctly reflect changes. If you need to write to such files, use AndroidFs::open_writable_stream.

  2. File mode restrictions:
    Files provided by third-party apps may not support writable modes other than FileAccessMode::Write. However, FileAccessMode::Write does not guarantee that existing contents will always be truncated.
    As a result, if the new contents are shorter than the original, the file may become corrupted. To avoid this, consider using AndroidFs::open_file_writable or AndroidFs::open_writable_stream, which ensure that existing contents are truncated and also automatically apply the maximum possible fallbacks.
    https://issuetracker.google.com/issues/180526528

§Args
§Support

All.

Source

pub fn open_file_with_fallback( &self, uri: &FileUri, candidate_modes: impl IntoIterator<Item = FileAccessMode>, ) -> Result<(File, FileAccessMode)>

For detailed documentation and notes, see AndroidFs::open_file.

The modes specified in candidate_modes are tried in order.
If the file can be opened, this returns the file along with the mode used.
If all attempts fail, an error is returned.

Source

pub fn open_writable_stream(&self, uri: &FileUri) -> Result<WritableStream<R>>

Opens a stream for writing to the specified file.
This truncates the existing contents.

§Usage

WritableStream implements std::io::Write, so it can be used for writing.
As with std::fs::File, wrap it with std::io::BufWriter if buffering is needed.

After writing, call WritableStream::reflect.

§Note

The behavior depends on AndroidFs::need_write_via_kotlin.
If it is false, this behaves like AndroidFs::open_file_writable.
If it is true, this behaves like AndroidFs::open_writable_stream_via_kotlin.

§Args
  • uri :
    Target file URI.
    This need to be writable.
§Support

All.

Source

pub fn open_writable_stream_via_kotlin( &self, uri: &FileUri, ) -> Result<WritableStream<R>>

Opens a writable stream to the specified file.
This truncates the existing contents.

This function always writes content via the Kotlin API, ensuring that writes to files not physically present on the device, such as cloud storage files, are properly applied. But this takes several times longer compared to AndroidFs::open_writable_stream.

AndroidFs::open_writable_stream automatically falls back to this function depending on AndroidFs::need_write_via_kotlin.
For performance reasons, it is strongly recommended to use AndroidFs::open_writable_stream if you can tolerate that AndroidFs::need_write_via_kotlin may not cover all cases.

§Usage

WritableStream implements std::io::Write, so it can be used for writing.
As with std::fs::File, wrap it with std::io::BufWriter if buffering is needed.

After writing, call WritableStream::reflect.

§Args
  • uri :
    Target file URI.
    This need to be writable.
§Support

All.

Source

pub fn read(&self, uri: &FileUri) -> Result<Vec<u8>>

Reads the entire contents of a file into a bytes vector.

§Args
  • uri :
    Target file URI.
    Must be readable.
§Support

All.

Source

pub fn read_to_string(&self, uri: &FileUri) -> Result<String>

Reads the entire contents of a file into a string.

§Args
  • uri :
    Target file URI.
    Must be readable.
§Support

All.

Source

pub fn write(&self, uri: &FileUri, contents: impl AsRef<[u8]>) -> Result<()>

Writes a slice as the entire contents of a file.
This function will entirely replace its contents if it does exist.

§Note

The behavior depends on AndroidFs::need_write_via_kotlin.
If it is false, this uses std::fs::File::write_all.
If it is true, this uses AndroidFs::write_via_kotlin.

§Args
  • uri :
    Target file URI.
    Must be writable.
§Support

All.

Source

pub fn write_via_kotlin( &self, uri: &FileUri, contents: impl AsRef<[u8]>, ) -> Result<()>

Writes a slice as the entire contents of a file.
This function will entirely replace its contents if it does exist.

This function always writes content via the Kotlin API, ensuring that writes to files not physically present on the device, such as cloud storage files, are properly applied. But this takes several times longer compared to AndroidFs::write.

AndroidFs::write automatically falls back to this function depending on AndroidFs::need_write_via_kotlin.
For performance reasons, it is strongly recommended to use AndroidFs::write if you can tolerate that AndroidFs::need_write_via_kotlin may not cover all cases.

§Support

All.

Source

pub fn copy(&self, src: &FileUri, dest: &FileUri) -> Result<()>

Copies the contents of the source file to the destination.
If the destination already has contents, they are truncated before writing the source contents.

§Note

The behavior depends on AndroidFs::need_write_via_kotlin.
If it is false, this uses std::io::copy with std::fs::File.
If it is true, this uses AndroidFs::copy_via_kotlin.

§Args
  • src :
    The URI of source file.
    Must be readable.

  • dest :
    The URI of destination file.
    Must be writable.

§Support

All.

Source

pub fn copy_via_kotlin( &self, src: &FileUri, dest: &FileUri, buffer_size: Option<u32>, ) -> Result<()>

Copies the contents of src file to dest.
If dest already has contents, it is truncated before write src contents.

This function always writes content via the Kotlin API, ensuring that writes to files not physically present on the device, such as cloud storage files, are properly applied.

AndroidFs::copy automatically falls back to this function depending on AndroidFs::need_write_via_kotlin.
For performance reasons, it is strongly recommended to use AndroidFs::copy if you can tolerate that AndroidFs::need_write_via_kotlin may not cover all cases.

§Args
  • src :
    The URI of source file.
    Must be readable.

  • dest :
    The URI of destination file.
    Must be writable.

  • buffer_size:
    The size of the buffer, in bytes, to use during the copy process on Kotlin.
    If None, DEFAULT_BUFFER_SIZE is used. At least, when I checked, it was 8 KB.
    If zero, this causes error.

§Support

All.

Source

pub fn need_write_via_kotlin(&self, uri: &FileUri) -> Result<bool>

Determines whether the file must be written via the Kotlin API rather than through a file descriptor.

Even if this returns false, it does not guarantee that writing via the Kotlin API is never required.

§Note

Currently, this function returns true only for files hosted by the following apps:

  • Google Drive
§Why

For files that do not physically exist on the device, such as those stored in cloud storage,
writing data through std::fs::File may not be properly reflected.
In such cases, the write operation must be performed via the Kotlin API.
https://community.latenode.com/t/csv-export-to-google-drive-results-in-empty-file-but-local-storage-works-fine

§Support

All.

Source

pub fn rename( &self, uri: &FileUri, new_name: impl AsRef<str>, ) -> Result<FileUri>

Renames a file or directory to a new name, and return new URI.
Even if the names conflict, the existing file will not be overwritten.

Note that when files or folders (and their descendants) are renamed, their URIs will change, and any previously granted permissions will be lost. In other words, this function returns a new URI without any permissions. However, for files created in PublicStorage, the URI remains unchanged even after such operations, and all permissions are retained. In this, this function returns the same URI as original URI.

§Args
  • uri :
    URI of target entry.

  • new_name :
    New name of target entry. This include extension if use.
    The behaviour in the same name already exists depends on the file provider.
    In the case of e.g. PublicStorage, the suffix (e.g. (1)) is added to this name.
    In the case of files hosted by other applications, errors may occur.
    But at least, the existing file will not be overwritten.

§Support

All.

Source

pub fn remove_file(&self, uri: &FileUri) -> Result<()>

Remove the file.

§Args
  • uri :
    Target file URI.
    Must be writable, at least. But even if it is, removing may not be possible in some cases. For details, refer to the documentation of the function that provided the URI.
    If not file, an error will occur.
§Support

All.

Source

pub fn remove_dir(&self, uri: &FileUri) -> Result<()>

Remove the empty directory.

§Args
  • uri :
    Target directory URI.
    Must be writable.
    If not empty directory, an error will occur.
§Support

All.

Source

pub fn remove_dir_all(&self, uri: &FileUri) -> Result<()>

Removes a directory and all its contents. Use carefully!

§Args
  • uri :
    Target directory URI.
    Must be writable.
    If not directory, an error will occur.
§Support

All.

Source

pub fn try_resolve_file_uri( &self, dir: &FileUri, relative_path: impl AsRef<str>, ) -> Result<FileUri>

Build a URI of an existing file located at the relative path from the specified directory.
Error occurs, if the file does not exist.

The permissions and validity period of the returned URI depend on the origin directory (e.g., the top directory selected by FilePicker::pick_dir)

§Support

All.

Source

pub fn try_resolve_dir_uri( &self, dir: &FileUri, relative_path: impl AsRef<str>, ) -> Result<FileUri>

Build a URI of an existing directory located at the relative path from the specified directory.
Error occurs, if the directory does not exist.

The permissions and validity period of the returned URI depend on the origin directory (e.g., the top directory selected by FilePicker::pick_dir)

§Support

All.

Source

pub fn resolve_uri( &self, dir: &FileUri, relative_path: impl AsRef<str>, ) -> Result<FileUri>

👎Deprecated: Use AndroidFs::try_resolve_file_uri or AndroidFs::try_resolve_dir_uri instead

Build a URI of an entry located at the relative path from the specified directory.

This function does not perform checks on the arguments or the returned URI.
Even if the dir argument refers to a file, no error occurs (and no panic either). Instead, it simply returns an invalid URI that will cause errors if used with other functions.

If you need check, consider using AndroidFs::try_resolve_file_uri or AndroidFs::try_resolve_dir_uri instead. Or use this with AndroidFs::get_mime_type.

The permissions and validity period of the returned URI depend on the origin directory (e.g., the top directory selected by FilePicker::pick_dir)

§Performance

This operation is relatively fast because it does not call Kotlin API and only involves operating strings on Rust side.

§Support

All.

Source

pub fn get_thumbnail_to( &self, src: &FileUri, dest: &FileUri, preferred_size: Size, format: ImageFormat, ) -> Result<bool>

See AndroidFs::get_thumbnail_to for descriptions.

If thumbnail does not wrote to dest, return false.

Source

pub fn get_thumbnail( &self, uri: &FileUri, preferred_size: Size, format: ImageFormat, ) -> Result<Option<Vec<u8>>>

Query the provider to get a file thumbnail.
If thumbnail does not exist it, return None.

Note this does not cache. Please do it in your part if need.

§Args
  • uri :
    Targe file uri.
    Thumbnail availablty depends on the file provider.
    In general, images and videos are available.
    For files in PrivateStorage, the file type must match the filename extension.

  • preferred_size :
    Optimal thumbnail size desired.
    This may return a thumbnail of a different size, but never more than double the requested size. In any case, the aspect ratio is maintained.

  • format :
    Thumbnail image format.
    ImageFormat::Jpeg is recommended. If you need transparency, use others.

§Support

All.

Source

pub fn create_file( &self, dir: &FileUri, relative_path: impl AsRef<str>, mime_type: Option<&str>, ) -> Result<FileUri>

Creates a new empty file in the specified location and returns a URI.

The permissions and validity period of the returned URIs depend on the origin directory (e.g., the top directory selected by FilePicker::pick_dir)

§Args
  • dir :
    The URI of the base directory.
    Must be read-write.

  • relative_path :
    The file path relative to the base directory.
    Any missing subdirectories in the specified path will be created automatically.
    If a file with the same name already exists, the system append a sequential number to ensure uniqueness.
    If no extension is present, the system may infer one from mime_type and may append it to the file name. But this append-extension operation depends on the model and version.

  • mime_type :
    The MIME type of the file to be created.
    If this is None, MIME type is inferred from the extension of relative_path and if that fails, application/octet-stream is used.

§Support

All.

Source

pub fn create_dir_all( &self, dir: &FileUri, relative_path: impl AsRef<str>, ) -> Result<FileUri>

Recursively create a directory and all of its parent components if they are missing, then return the URI.
If it already exists, do nothing and just return the direcotry uri.

AndroidFs::create_file does this automatically, so there is no need to use it together.

§Args
  • dir :
    The URI of the base directory.
    Must be read-write.

  • relative_path :
    The directory path relative to the base directory.

§Support

All.

Source

pub fn read_dir(&self, uri: &FileUri) -> Result<impl Iterator<Item = Entry>>

Returns the child files and directories of the specified directory.
The order of the entries is not guaranteed.

The permissions and validity period of the returned URIs depend on the origin directory (e.g., the top directory selected by FilePicker::pick_dir)

§Note

The returned type is an iterator, but the file system call is not executed lazily.
Instead, all data is retrieved at once.
For directories containing thousands or even tens of thousands of entries,
this function may take several seconds to complete.
The returned iterator itself is low-cost, as it only performs lightweight data formatting.

§Args
  • uri :
    Target directory URI.
    Must be readable.
§Support

All.

Source

pub fn resolve_initial_location<'a>( &self, dir: impl Into<InitialLocation<'a>>, create_dirs: bool, ) -> Result<FileUri>

Create an restricted URI for the specified directory.
This should only be used as initial_location in the file picker. It must not be used for any other purpose.

This is useful when selecting (creating) new files and folders, but when selecting existing entries, initial_location is often better with None.

Note this is an informal method and is not guaranteed to work reliably. But this URI does not cause the dialog to error.
So please use this with the mindset that it’s better than doing nothing.

§Examples
 use tauri_plugin_android_fs::{AndroidFsExt, InitialLocation, PublicGeneralPurposeDir, PublicImageDir};

fn sample(app: tauri::AppHandle) {
    let api = app.android_fs();

    // Get URI of the top public directory in primary volume
    let initial_location = api.resolve_initial_location(
        InitialLocation::TopPublicDir,
        false,
    ).expect("Should be on Android");

    // Get URI of ~/Pictures/
    let initial_location = api.resolve_initial_location(
        PublicImageDir::Pictures,
        false
    ).expect("Should be on Android");

    // Get URI of ~/Documents/sub_dir1/sub_dir2/
    let initial_location = api.resolve_initial_location(
        InitialLocation::DirInPublicDir {
            base_dir: PublicGeneralPurposeDir::Documents.into(),
            relative_path: "sub_dir1/sub_dir2"
        },
        true // Create dirs of 'sub_dir1' and 'sub_dir2', if not exists
    ).expect("Should be on Android");

    // Open dialog with initial_location
    let _ = api.file_picker().save_file(Some(&initial_location), "", None);
    let _ = api.file_picker().pick_file(Some(&initial_location), &[]);
    let _ = api.file_picker().pick_dir(Some(&initial_location));
}
§Support

All.

Note :

Source

pub fn take_persistable_uri_permission(&self, uri: &FileUri) -> Result<()>

Take persistent permission to access the file, directory and its descendants.
This is a prolongation of an already acquired permission, not the acquisition of a new one.

This works by just calling, without displaying any confirmation to the user.

Note that there is a limit to the total number of URI that can be made persistent by this function.
Therefore, it is recommended to relinquish the unnecessary persisted URI by AndroidFs::release_persisted_uri_permission or AndroidFs::release_all_persisted_uri_permissions.
Persisted permissions may be relinquished by other apps, user, or by moving/removing entries. So check by AndroidFs::check_persisted_uri_permission.
And you can retrieve the list of persisted uris using AndroidFs::get_all_persisted_uri_permissions.

§Args
§Support

All.

Source

pub fn check_persisted_uri_permission( &self, uri: &FileUri, mode: PersistableAccessMode, ) -> Result<bool>

Check a persisted URI permission grant by AndroidFs::take_persistable_uri_permission.
Returns false if there are only non-persistent permissions or no permissions.

§Args
  • uri :
    URI of the target file or directory.
    If this is via AndroidFs::read_dir, the permissions of the origin directory URI is checked, not a entry iteself. Because the permissions and validity period of the entry URIs depend on the origin directory.

  • mode :
    The mode of permission you want to check.

§Support

All.

Source

pub fn get_all_persisted_uri_permissions( &self, ) -> Result<impl Iterator<Item = PersistedUriPermission>>

Return list of all persisted URIs that have been persisted by AndroidFs::take_persistable_uri_permission and currently valid.

§Support

All.

Source

pub fn release_persisted_uri_permission(&self, uri: &FileUri) -> Result<()>

Relinquish a persisted URI permission grant by AndroidFs::take_persistable_uri_permission.

§Args
  • uri :
    URI of the target file or directory.
§Support

All.

Source

pub fn release_all_persisted_uri_permissions(&self) -> Result<()>

Relinquish a all persisted uri permission grants by AndroidFs::take_persistable_uri_permission.

§Support

All.

Source

pub fn is_available(&self) -> bool

Verify whether this plugin is available.

On Android, this returns true.
On other platforms, this returns false.

Source

pub fn api_level(&self) -> Result<usize>

Get the api level of this Android device.

The correspondence table between API levels and Android versions can be found following.
https://developer.android.com/guide/topics/manifest/uses-sdk-element#api-level-table

Android versionAPI Level
16.036
15.035
14.034
13.033
12L32
12.031
11.030
10.029
9.028
8.127
8.026
7.1 - 7.1.225
7.024

Tauri does not support Android versions below 7.

Source

pub fn write_via_kotlin_in<T>( &self, uri: &FileUri, contents_writer: impl FnOnce(&mut File) -> Result<T>, ) -> Result<T>

👎Deprecated: Use AndroidFs::open_writable_stream_via_kotlin instead.

See AndroidFs::write_via_kotlin for information.
Use this if you want to write using std::fs::File, not entire contents.

§Args
  • uri :
    Target file URI to write.

  • contetns_writer :
    A closure that accepts a mutable reference to a std::fs::File and performs the actual write operations. Note that this represents a temporary file.

Auto Trait Implementations§

§

impl<R> Freeze for AndroidFs<R>

§

impl<R> RefUnwindSafe for AndroidFs<R>

§

impl<R> Send for AndroidFs<R>

§

impl<R> Sync for AndroidFs<R>

§

impl<R> Unpin for AndroidFs<R>

§

impl<R> UnwindSafe for AndroidFs<R>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> ErasedDestructor for T
where T: 'static,