Note: **I’m using a translation tool, so there may be some inappropriate expressions.**
# Overview
The Android file system is strict and complex. This plugin was created to provide practical file operations. You don’t need to set special permissions or configurations.
# Setup
Register this plugin in your Tauri project:
`src-tauri/src/lib.rs`
```rust
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
// Add following
.plugin(tauri_plugin_android_fs::init())
//
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
```
# Usage
This plugin only provides a Rust-side API.
If you need to use file data on frontend, consider using Tauri’s custom protocols for efficient transmission. Or convert `tauri_plugin_android_fs::FileUri` to `tauri_plugin_fs::FilePath` and use tauri_plugin_fs functions on frontend.
### 1. Dialog
Opens the file/folder picker to read and write user-selected entries.
```rust
use tauri_plugin_android_fs::{AndroidFsExt, ImageFormat, Size};
fn file_picker_example(app: tauri::AppHandle) -> tauri_plugin_android_fs::Result<()> {
let api = app.android_fs();
// Pick files to read and write
let selected_files = api.file_picker().pick_files(
None, // Initial location
&["*/*"], // Target MIME types
)?;
if selected_files.is_empty() {
// Handle cancel
}
else {
for uri in selected_files {
// This is FilePath::Url(..)
// Not FilePath::Path(..)
let file_path: tauri_plugin_fs::FilePath = uri.clone().into();
let file_type = api.get_mime_type(&uri)?;
let file_name = api.get_name(&uri)?;
let file_thumbnail = api.get_thumbnail(
&uri,
Size { width: 200, height: 200},
ImageFormat::Jpeg
)?;
{
// Handle readonly file.
let file: std::fs::File = api.open_file_readable(&uri)?;
}
{
// Handle writeonly file.
// This truncate existing contents.
let file: std::fs::File = api.open_file_writable(&uri)?;
// But if you can, use 'open_writable_stream',
// considering the possibility that files may be on cloud storage.
use std::io::{BufWriter, Write as _};
let mut stream = api.open_writable_stream(&uri)?;
stream.write_all(&[])?;
stream.reflect()?;
let mut stream = BufWriter::new(api.open_writable_stream(&uri)?);
stream.write_all(&[])?;
stream.into_inner()?.reflect()?;
}
}
}
Ok(())
}
```
```rust
use tauri_plugin_android_fs::{AndroidFsExt, Entry};
fn dir_picker_example(app: tauri::AppHandle) -> tauri_plugin_android_fs::Result<()> {
let api = app.android_fs();
// Pick directory to read and write
let selected = api.file_picker().pick_dir(
None, // Initial location
)?;
if let Some(dir_uri) = selected {
// Persist access permission across app restarts.
api.take_persistable_uri_permission(&dir_uri)?;
// Read the directory
for entry in api.read_dir(&dir_uri)? {
match entry {
Entry::File { name, uri, last_modified, len, mime_type, .. } => {
// Handle file
},
Entry::Dir { name, uri, last_modified, .. } => {
// Handle directory
},
}
}
// Create a new file in the directory
let file_uri = api.create_new_file(
&dir_uri,
"MyApp/file.txt",
Some("text/plain")
)?;
}
else {
// Handle cancel
}
Ok(())
}
```
### 2. Public Storage
File storage that is available to other applications and users.
This is for Android 10 (API level 29) or higher.
```rust
use tauri_plugin_android_fs::{AndroidFsExt, PublicGeneralPurposeDir, PublicImageDir};
fn example(app: tauri::AppHandle) -> tauri_plugin_android_fs::Result<()> {
let api = app.android_fs();
let storage = api.public_storage();
let contents = &[];
// Create a new empty PNG image file
//
// ~/Pictures/{app_name}/my-image.png
let uri = storage.create_new_file(
None, // Storage volume. If None, use primary storage volume
PublicImageDir::Pictures, // Base directory
true, // Insert app name directory between base directory and relative path
"my-image.png", // Relative file path
Some("image/png") // Mime type
)?;
// Write the contents to the PNG image
if let Err(e) = api.write(&uri, contents) {
// handle err
let _ = api.remove_file(&uri);
return Err(e)
}
// Get any available volume other than the primary one
// (e.g., SD card, USB drive)
let volume = storage.get_volumes()?
.into_iter()
.find(|v| !v.is_primary);
let uri = storage.create_new_file(
volume.as_ref().map(|v| &v.id), // Storage volume.
PublicGeneralPurposeDir::Documents, // Base directory
true, // Insert app name dir between base directory and relative path
"2025-9-14/data.txt", // Relative file path
Some("text/plain") // Mime type
)?;
let mut file: std::fs::File = api.open_file_writable(&uri)?;
Ok(())
}
```
### 3. Private Storage
File storage intended for the app’s use only.
```rust
use tauri_plugin_android_fs::{AndroidFsExt, PrivateDir};
fn example(app: tauri::AppHandle) -> tauri_plugin_android_fs::Result<()> {
let storage = app.android_fs().private_storage();
// Get the absolute path.
// Apps can fully manage entries within those directories with 'std::fs'.
let cache_dir_path: std::path::PathBuf = storage.resolve_path(PrivateDir::Cache)?;
let data_dir_path: std::path::PathBuf = storage.resolve_path(PrivateDir::Data)?;
Ok(())
}
```
# Link
- [Changelog](https://github.com/aiueo13/tauri-plugin-android-fs/blob/main/CHANGES.md)
# License
MIT OR Apache-2.0