PublicStorage

Struct PublicStorage 

Source
pub struct PublicStorage<'a, R: Runtime>(/* private fields */);
Expand description

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

§Examples

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

Implementations§

Source§

impl<'a, R: Runtime> PublicStorage<'a, R>

Source

pub fn get_available_volumes(&self) -> Result<Vec<PublicStorageVolume>>

Gets a list of currently available storage volumes (internal storage, SD card, USB drive, etc.). Be aware of TOCTOU.

This typically includes primary storage volume, but it may occasionally be absent if the primary volume is inaccessible (e.g., mounted on a computer, removed, or another issue).

Primary storage volume is always listed first, if included. But the order of the others is not guaranteed.

§Note

The volume represents the logical view of a storage volume for an individual user: each user may have a different view for the same physical volume (e.g. when the volume is a built-in emulated storage).

§Support

Android 10 (API level 29) or higher.

Source

pub fn get_primary_volume(&self) -> Result<PublicStorageVolume>

Gets a primary storage volume.
This is the most common and recommended storage volume for placing files that can be accessed by other apps or user.

A device always has one (and one only) primary storage volume.

The returned primary volume may not currently be accessible if it has been mounted by the user on their computer, has been removed from the device, or some other problem has happened.

You can find a list of all currently available volumes using PublicStorage::get_available_volumes.

§Note

The volume represents the logical view of a storage volume for an individual user: each user may have a different view for the same physical volume (e.g. when the volume is a built-in emulated storage).

The primary volume provides a separate area for each user in a multi-user environment.

§Support

Android 10 (API level 29) or higher.

§References

https://developer.android.com/reference/android/provider/MediaStore#VOLUME_EXTERNAL_PRIMARY

Source

pub fn create_file_in_app_dir( &self, volume: Option<&PublicStorageVolumeId>, dir: impl Into<PublicDir>, relative_path: impl AsRef<str>, mime_type: Option<&str>, ) -> Result<FileUri>

Creates a new empty file in the app folder of the specified public directory and returns a persistent read-write URI.

The created file has the following features:

  • It is registered with the appropriate MediaStore as needed.
  • The app can fully manage it until the app is uninstalled.
  • It is not removed when the app itself is uninstalled.

This is equivalent to:

let app_name = public_storage.app_dir_name()?;
public_storage.create_file(
    volume,
    dir,
    format!("{app_name}/{relative_path}"),
    mime_type
)?;
§Args
  • volume :
    The storage volume, such as internal storage, SD card, etc.
    Usually, you don’t need to specify this unless there is a special reason.
    If None is provided, the primary storage volume will be used.

  • dir :
    The base directory.
    When using PublicImageDir, use only image MIME types for mime_type, which is discussed below.; using other types may cause errors. Similarly, use only the corresponding media types for PublicVideoDir and PublicAudioDir. Only PublicGeneralPurposeDir supports all MIME types.

  • 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

Android 10 (API level 29) or higher.

Note :

Source

pub fn create_file( &self, volume: Option<&PublicStorageVolumeId>, dir: impl Into<PublicDir>, relative_path_with_subdir: impl AsRef<str>, mime_type: Option<&str>, ) -> Result<FileUri>

Creates a new empty file in the specified public directory and returns a persistent read-write URI.

The created file has the following features:

  • It is registered with the appropriate MediaStore as needed.
  • The app can fully manage it until the app is uninstalled.
  • It is not removed when the app itself is uninstalled.
§Args
  • volume :
    The storage volume, such as internal storage, SD card, etc.
    Usually, you don’t need to specify this unless there is a special reason.
    If None is provided, the primary storage volume will be used.

  • dir :
    The base directory.
    When using PublicImageDir, use only image MIME types for mime_type, which is discussed below.; using other types may cause errors. Similarly, use only the corresponding media types for PublicVideoDir and PublicAudioDir. Only PublicGeneralPurposeDir supports all MIME types.

  • relative_path_with_subdir :
    The file path relative to the base directory.
    Please specify a subdirectory in this, such as MyApp/file.txt or MyApp/2025-2-11/file.txt. Do not use file.txt.
    As shown above, it is customary to specify the app name at the beginning of the subdirectory, and in this case, using PublicStorage::create_file_in_app_dir is recommended.
    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_with_subdir and if that fails, application/octet-stream is used.

§Support

Android 10 (API level 29) or higher.

Note :

Source

pub fn create_dir_all( &self, volume: Option<&PublicStorageVolumeId>, dir: impl Into<PublicDir>, relative_path: impl AsRef<str>, ) -> Result<()>

Recursively create a directory and all of its parent components if they are missing.
If it already exists, do nothing.

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

§Args
  • volume :
    The storage volume, such as internal storage, SD card, etc.
    If None is provided, the primary storage volume will be used.

  • dir :
    The base directory.

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

§Support

Android 10 (API level 29) or higher.

Note :

Source

pub fn create_dir_all_in_app_dir( &self, volume: Option<&PublicStorageVolumeId>, dir: impl Into<PublicDir>, relative_path: impl AsRef<str>, ) -> Result<()>

Recursively create a directory and all of its parent components if they are missing.
If it already exists, do nothing.

PublicStorage::create_file_in_app_dir does this automatically, so there is no need to use it together.

This is the same as following:

let app_name = public_storage.app_dir_name()?;
public_storage.create_dir_all(
    volume,
    dir,
    format!("{app_name}/{relative_path}"),
)?;
§Args
  • volume :
    The storage volume, such as internal storage, SD card, etc.
    If None is provided, the primary storage volume will be used.

  • dir :
    The base directory.

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

§Support

Android 10 (API level 29) or higher.

Note :

Source

pub fn resolve_initial_location( &self, initial_location: InitialLocation<'_>, create_dir_all: bool, ) -> Result<FileUri>

Create the specified directory URI that has no permissions.

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 save location, but when selecting existing entries, initial_location is often better with None.

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

fn example(app: tauri::AppHandle) -> tauri_plugin_android_fs::Result<()> {
    let api = app.android_fs();
    let public_storage = api.public_storage();

    // Get URI of the top public directory in primary volume
    let initial_location = public_storage.resolve_initial_location(
        InitialLocation::PrimaryTopDir, 
        false
    )?;

    api.file_picker().pick_file(Some(&initial_location), &[])?;
    api.file_picker().pick_dir(Some(&initial_location))?;
    api.file_picker().save_file(Some(&initial_location), "file_name", Some("image/png"))?;


    // Get URI of ~/Pictures/ in primary volume
    let initial_location = public_storage.resolve_initial_location(
        InitialLocation::PrimaryPublicDir { 
            dir: PublicImageDir::Pictures.into(), 
            relative_path: "" 
        }, 
        false
    )?;

    // Get URI of ~/Documents/sub_dir1/sub_dir2/ in primary volume
    let initial_location = public_storage.resolve_initial_location(
        InitialLocation::PrimaryPublicDir { 
            dir: PublicGeneralPurposeDir::Documents.into(), 
            relative_path: "sub_dir1/sub_dir2" 
        }, 
        true, // Create "sub_dir1" and "sub_dir2" directories if missing
    )?;


    let volumes = public_storage.get_available_volumes()?;
    let primary_volume = public_storage.get_primary_volume()?;

    // Get any available volume other than the primary one 
    // (e.g., SD card or USB drive); 
    // 
    // if none, use the primary volume.
    let volume = volumes.into_iter()
        .find(|v| !v.is_primary)
        .unwrap_or(primary_volume);

    // Get URI of the top public directory in the specified volume
    let initial_location = public_storage.resolve_initial_location(
        InitialLocation::TopDir {
            volume: &volume.id
        }, 
        false
    )?;

    // Get URI of ~/Movies/ in the specified volume
    let initial_location = public_storage.resolve_initial_location(
        InitialLocation::PublicDir {
            volume: &volume.id,
            dir: PublicVideoDir::Movies.into(),
            relative_path: ""
        }, 
        false
    )?;
     

    Ok(())
}
§Support

All Android version.

Note :

Source

pub fn is_available(&self) -> Result<bool>

Verify whether the basic functions of PublicStorage (such as PublicStorage::create_file) can be performed.

If on Android 9 (API level 28) and lower, this returns false.
If on Android 10 (API level 29) or higher, this returns true.

§Support

All Android version.

Source

pub fn is_audiobooks_dir_available(&self) -> Result<bool>

Verify whether PublicAudioDir::Audiobooks is available on a given device.

If on Android 9 (API level 28) and lower, this returns false.
If on Android 10 (API level 29) or higher, this returns true.

§Support

All Android version.

Source

pub fn is_recordings_dir_available(&self) -> Result<bool>

Verify whether PublicAudioDir::Recordings is available on a given device.

If on Android 11 (API level 30) and lower, this returns false.
If on Android 12 (API level 31) or higher, this returns true.

§Support

All Android version.

Source

pub fn app_dir_name(&self) -> Result<&str>

Resolve the app dir name from Tauri’s config.

§Support

All Android version.

Auto Trait Implementations§

§

impl<'a, R> Freeze for PublicStorage<'a, R>

§

impl<'a, R> RefUnwindSafe for PublicStorage<'a, R>

§

impl<'a, R> Send for PublicStorage<'a, R>

§

impl<'a, R> Sync for PublicStorage<'a, R>

§

impl<'a, R> Unpin for PublicStorage<'a, R>

§

impl<'a, R> UnwindSafe for PublicStorage<'a, 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,