Skip to main content

tauri_plugin_android_fs/
lib.rs

1//! Overview and usage is [here](https://crates.io/crates/tauri-plugin-android-fs)
2
3#![cfg_attr(not(target_os = "android"), allow(unused_variables))]
4
5mod cmds;
6mod protocols;
7mod config;
8mod scope;
9mod utils;
10
11pub mod api;
12
13use utils::*;
14
15pub use api::models::*;
16pub use api::consts::*;
17
18/// Initializes the plugin.
19/// 
20/// # Usage
21/// `src-tauri/src/lib.rs`
22/// ```
23/// #[cfg_attr(mobile, tauri::mobile_entry_point)]
24/// pub fn run() {
25///     tauri::Builder::default()
26///         .plugin(tauri_plugin_android_fs::init())
27///         .run(tauri::generate_context!())
28///         .expect("error while running tauri application");
29/// }
30/// ```
31pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R, Option<config::Config>> {
32    let builder = tauri::plugin::Builder::<R, Option<config::Config>>::new("android-fs")
33        .setup(|app, api| {
34            use tauri::Manager as _;
35
36            #[cfg(target_os = "android")] {
37                let handle = api.register_android_plugin("com.plugin.android_fs", "AndroidFsPlugin")?;
38                let afs_sync = crate::api::api_sync::AndroidFs { handle: handle.clone() };
39                let afs_async = crate::api::api_async::AndroidFs { handle: handle.clone() };
40                app.manage(afs_sync);
41                app.manage(afs_async);
42
43                #[cfg(feature = "commands")] {
44                    app.manage(cmds::new_file_stream_resources_state(app.app_handle().clone()));
45                    app.manage(cmds::new_file_writer_resources_state(app.app_handle().clone()));
46                }
47
48                #[cfg(any(feature = "protocol_content", feature = "protocol_thumbnail"))] {
49                    app.manage(protocols::new_config_state(api.config().as_ref(), app));
50                }
51            }
52            #[cfg(not(target_os = "android"))] {
53                let afs_sync = crate::api::api_sync::AndroidFs::<R> { handle: Default::default() };
54                let afs_async = crate::api::api_async::AndroidFs::<R> { handle: Default::default() };
55                app.manage(afs_sync);
56                app.manage(afs_async);
57            }
58
59            Ok(())
60        });
61
62    #[cfg(feature = "commands")]
63    let builder = builder
64        .js_init_script(format!(
65            "window.__TAURI_ANDROID_FS_PLUGIN_INTERNALS__ = {{ isAndroid: {} }};",
66            cfg!(target_os = "android")
67        ))
68        .invoke_handler(tauri::generate_handler![
69            cmds::get_android_api_level,
70            cmds::get_name,
71            cmds::get_type,
72            cmds::get_metadata,
73            cmds::get_file_byte_length,
74            cmds::get_file_mime_type,
75            cmds::get_file_thumbnail,
76            cmds::get_file_thumbnail_as_base64,
77            cmds::get_file_thumbnail_as_data_url,
78            cmds::list_volumes,
79            cmds::create_new_public_file,
80            cmds::create_new_public_image_file,
81            cmds::create_new_public_video_file,
82            cmds::create_new_public_audio_file,
83            cmds::scan_public_file,
84            cmds::set_public_file_pending,
85            cmds::request_public_files_permission,
86            cmds::check_public_files_permission,
87            cmds::create_new_file,
88            cmds::create_new_dir,
89            cmds::create_dir,
90            cmds::count_all_file_streams,
91            cmds::close_all_file_streams,
92            cmds::open_read_file_stream,
93            cmds::open_read_text_file_lines_stream,
94            cmds::open_write_file_stream,
95            cmds::read_file,
96            cmds::read_file_as_base64,
97            cmds::read_file_as_data_url,
98            cmds::read_text_file,
99            cmds::write_file,
100            cmds::write_text_file,
101            cmds::copy_file,
102            cmds::truncate_file,
103            cmds::read_dir,
104            cmds::rename_file,
105            cmds::rename_dir,
106            cmds::remove_file,
107            cmds::remove_empty_dir,
108            cmds::remove_dir_all,
109            cmds::check_picker_uri_permission,
110            cmds::persist_picker_uri_permission,
111            cmds::check_persisted_picker_uri_permission,
112            cmds::release_persisted_picker_uri_permission,
113            cmds::release_all_persisted_picker_uri_permissions,
114            cmds::show_open_file_picker,
115            cmds::show_open_dir_picker,
116            cmds::show_save_file_picker,
117            cmds::show_share_file_app_chooser,
118            cmds::show_view_file_app_chooser,
119            cmds::show_view_dir_app_chooser,
120            cmds::show_edit_file_app_chooser,
121        ]);
122
123    #[cfg(all(target_os = "android", feature = "protocol_thumbnail"))]
124    let builder = builder
125        .register_asynchronous_uri_scheme_protocol(
126            protocols::protocol_thumbnail::URI_SCHEME, 
127            protocols::protocol_thumbnail::protocol,
128        );
129
130    #[cfg(all(target_os = "android", feature = "protocol_content"))]
131    let builder = builder
132        .register_asynchronous_uri_scheme_protocol(
133            protocols::protocol_content::URI_SCHEME, 
134            protocols::protocol_content::protocol,
135        );
136    
137    builder.build()
138}
139
140pub trait AndroidFsExt<R: tauri::Runtime> {
141
142    /// Provides an API for accessing the Android file system.
143    /// 
144    /// It is a blocking-based API. If you need an asynchronous API, use [`AndroidFsExt::android_fs_async`].
145    fn android_fs(&self) -> &api::api_sync::AndroidFs<R>;
146
147    /// Provides an asynchronous API for accessing the Android file system.
148    fn android_fs_async(&self) -> &api::api_async::AndroidFs<R>;
149}
150
151impl<R: tauri::Runtime, T: tauri::Manager<R>> AndroidFsExt<R> for T {
152
153    fn android_fs(&self) -> &api::api_sync::AndroidFs<R> {
154        self.try_state::<api::api_sync::AndroidFs<R>>()
155            .map(|i| i.inner())
156            .expect("tauri_plugin_android_fs should be initialized to use; see https://crates.io/crates/tauri-plugin-android-fs")
157    }
158
159    fn android_fs_async(&self) -> &api::api_async::AndroidFs<R> {
160        self.try_state::<api::api_async::AndroidFs<R>>()
161            .map(|i| i.inner())
162            .expect("tauri_plugin_android_fs should be initialized to use; see https://crates.io/crates/tauri-plugin-android-fs")
163    }
164}