tauri_plugin_android_fs/api/
file_sender.rs

1use crate::*;
2
3
4/// API of sharing files with other apps.
5/// 
6/// # Examples
7/// ```
8/// fn example(app: &tauri::AppHandle) {
9///     use tauri_plugin_android_fs::AndroidFsExt as _;
10/// 
11///     let api = app.android_fs();
12///     let file_sender = api.file_sender();
13/// }
14/// ```
15pub struct FileSender<'a, R: tauri::Runtime>(
16    #[allow(unused)]
17    pub(crate) &'a AndroidFs<R>
18);
19
20impl<'a, R: tauri::Runtime> FileSender<'a, R> {
21
22    /// Show app chooser for sharing files with other apps.   
23    /// This function returns immediately after requesting to open the app chooser, 
24    /// without waiting for the app’s response. 
25    /// 
26    /// This sends the files as a single unit.
27    /// The available apps depend on the MIME types associated with the files.  
28    /// This does not result in an error even if no available apps are found. 
29    /// An empty app chooser is displayed.
30    /// 
31    /// # Args
32    /// - ***uris*** :  
33    /// Target file URIs to share.  
34    /// This all needs to be **readable**.  
35    /// Files in [`PrivateStorage`] **cannot** be used. 
36    /// 
37    /// # Support
38    /// All Android version.
39    /// 
40    /// # References
41    /// <https://developer.android.com/reference/android/content/Intent#ACTION_SEND_MULTIPLE>
42    /// <https://developer.android.com/reference/android/content/Intent#ACTION_SEND>
43    pub fn share_files<'b>(
44        &self, 
45        uris: impl IntoIterator<Item = &'b FileUri>, 
46    ) -> crate::Result<()> {
47
48        // もし use_app_chooser と exclude_self_from_app_chooser を関数の引数として公開するなら、
49        //  Show app chooser for sharing files with other apps.   
50        //. This function returns immediately after requesting to open the app chooser, 
51        // を以下に変更した方が説明文としてわかりやすいかもしれない。
52        //  Share files with other app that user selected. 
53        //  This function returns immediately after requesting to share the files, 
54
55        on_android!({
56            impl_se!(struct Req<'a> { uris: Vec<&'a FileUri>, common_mime_type: Option<&'a str>, use_app_chooser: bool, exclude_self_from_app_chooser: bool });
57            impl_de!(struct Res;);
58
59            // Decides whether the app chooser dialog is always shown.  
60            // The recommended value is true, which ensures the dialog is always displayed.  
61            // If set to false, the behavior depends on the user’s previous choice: 
62            // if the user has previously selected an app as "ALWAYS" in Android, 
63            // that app will be opened directly. 
64            // Otherwise, the app list will appear, offering both the "JUST ONCE" and "ALWAYS" options.
65            //
66            // NOTE:
67            // これがfalseの場合も、対応できるアプリがない場合にエラーが発生することはない。
68            // ただ何も起こらないのでユーザー的にはあまり良くない。
69            // trueの場合は空のapp chooserと「対応できるアプリがありません」のようなテキストが表示される。
70            let use_app_chooser = true;
71
72            // Decides whether to exclude this app from the app chooser.  
73            // This is effective only if this app is configured to receive [`INTENT.ACTION_SEND_MULTIPLE`](https://developer.android.com/reference/android/content/Intent#ACTION_SEND_MULTIPLE) or [`INTENT.ACTION_SEND`](https://developer.android.com/reference/android/content/Intent#ACTION_SEND).    
74            // If set to true, ***use_app_chooser*** must also be true and on Android 7 or later; 
75            // otherwise, this setting will be ignored. 
76            let exclude_self_from_app_chooser = true;
77
78            // Noneの場合、共有するファイルに設定されているMIME typeを用いる
79            let common_mime_type = None;
80
81            let uris = uris.into_iter().collect::<Vec<_>>();
82
83            self.0.api
84                .run_mobile_plugin::<Res>("shareFiles", Req { uris, common_mime_type, use_app_chooser, exclude_self_from_app_chooser })
85                .map(|_| ())
86                .map_err(Into::into)
87        })
88    }
89
90    /// Show app chooser for sharing file with other apps.    
91    /// This function returns immediately after requesting to open the app chooser, 
92    /// without waiting for the app’s response. 
93    /// 
94    /// The available apps depend on the MIME type associated with the file.  
95    /// This does not result in an error even if no available apps are found. 
96    /// An empty app chooser is displayed.
97    /// 
98    /// # Args
99    /// - ***uri*** :  
100    /// Target file URI to share.  
101    /// Must be **readable**.  
102    /// Files in [`PrivateStorage`] **cannot** be used.
103    /// 
104    /// # Support
105    /// All Android version.
106    /// 
107    /// # References
108    /// <https://developer.android.com/reference/android/content/Intent#ACTION_SEND>
109    pub fn share_file(
110        &self, 
111        uri: &FileUri,
112    ) -> crate::Result<()> {
113        
114        self.share_files([uri])
115    }
116
117    /// Show app chooser for opening file with other apps.   
118    /// This function returns immediately after requesting to open the app chooser, 
119    /// without waiting for the app’s response. 
120    /// 
121    /// The available apps depend on the MIME type associated with the file.  
122    /// This does not result in an error even if no available apps are found. 
123    /// An empty app chooser is displayed.
124    /// 
125    /// # Args
126    /// - ***uri*** :  
127    /// Target file URI to view.  
128    /// Must be **readable**.  
129    /// Files in [`PrivateStorage`] **cannot** be used.
130    /// 
131    /// # Support
132    /// All Android version.
133    /// 
134    /// # References
135    /// <https://developer.android.com/reference/android/content/Intent#ACTION_VIEW>
136    pub fn open_file(
137        &self, 
138        uri: &FileUri,
139    ) -> crate::Result<()> {
140
141        on_android!({
142            impl_se!(struct Req<'a> { uri: &'a FileUri, mime_type: Option<&'a str>, use_app_chooser: bool, exclude_self_from_app_chooser: bool });
143            impl_de!(struct Res;);
144
145            let use_app_chooser = true;
146            let exclude_self_from_app_chooser = true;
147            let mime_type = None;
148    
149            self.0.api
150                .run_mobile_plugin::<Res>("viewFile", Req { uri, mime_type, use_app_chooser, exclude_self_from_app_chooser })
151                .map(|_| ())
152                .map_err(Into::into)
153        })
154    }
155
156    /// Show app chooser for editing file with other apps.   
157    /// This function returns immediately after requesting to open the app chooser, 
158    /// without waiting for the app’s response. 
159    /// 
160    /// The available apps depend on the MIME type associated with the file.  
161    /// This does not result in an error even if no available apps are found. 
162    /// An empty app chooser is displayed.
163    /// 
164    /// # Note
165    /// I think that this may be the least commonly used request for sending file to app.  
166    /// Even if you want to open an image or video editing app, 
167    /// [`FileSender::open_file`] allows you to choose from a wider range of apps in many cases.
168    /// 
169    /// # Args
170    /// - ***uri*** :  
171    /// Target file URI to view.  
172    /// Must be **read-writeable**.  
173    /// Files in [`PrivateStorage`] **cannot** be used.
174    /// 
175    /// # Support
176    /// All Android version.
177    /// 
178    /// # References
179    /// <https://developer.android.com/reference/android/content/Intent#ACTION_EDIT>
180    pub fn edit_file(
181        &self, 
182        uri: &FileUri,
183    ) -> crate::Result<()> {
184
185        on_android!({
186            impl_se!(struct Req<'a> { uri: &'a FileUri, mime_type: Option<&'a str>, use_app_chooser: bool, exclude_self_from_app_chooser: bool });
187            impl_de!(struct Res;);
188
189            let use_app_chooser = true;
190            let exclude_self_from_app_chooser = true;
191            let mime_type = None;
192    
193            self.0.api
194                .run_mobile_plugin::<Res>("editFile", Req { uri, mime_type, use_app_chooser, exclude_self_from_app_chooser })
195                .map(|_| ())
196                .map_err(Into::into)
197        })
198    }
199
200    /// Determines whether the specified files can be used with [`FileSender::share_files`].  
201    /// If no app is available to handle the files, this returns false. 
202    /// 
203    /// # Args
204    /// - ***uris*** :  
205    /// Target file URIs to share.  
206    /// This all needs to be **readable**.  
207    /// 
208    /// # Support
209    /// All Android version.
210    #[deprecated = "Since Android 11, This does not function correctly due to android security."]
211    pub fn can_share_files<'b>(
212        &self, 
213        uris: impl IntoIterator<Item = &'b FileUri>, 
214    ) -> crate::Result<bool> {
215
216        on_android!({
217            impl_se!(struct Req<'a> { uris: Vec<&'a FileUri>, common_mime_type: Option<&'a str> });
218            impl_de!(struct Res { value: bool });
219
220            let common_mime_type = None;
221            let uris = uris.into_iter().collect::<Vec<_>>();
222
223            self.0.api
224                .run_mobile_plugin::<Res>("canShareFiles", Req { uris, common_mime_type })
225                .map(|v| v.value)
226                .map_err(Into::into)
227        })
228    }
229
230    /// Determines whether the specified file can be used with [`FileSender::share_file`].  
231    /// If no app is available to handle the file, this returns false. 
232    /// 
233    /// # Args
234    /// - ***uri*** :  
235    /// Target file URI.  
236    /// Must be **readable**.
237    /// 
238    /// # Support
239    /// All Android version.
240    #[deprecated = "Since Android 11, This does not function correctly due to android security."]
241    pub fn can_share_file(&self, uri: &FileUri) -> crate::Result<bool> {
242        #[allow(deprecated)]
243        self.can_share_files([uri])
244    }
245
246    /// Determines whether the specified file can be used with [`FileSender::open_file`].  
247    /// If no app is available to handle the file, this returns false. 
248    /// 
249    /// # Args
250    /// - ***uri*** :  
251    /// Target file URI.  
252    /// Must be **readable**.
253    /// 
254    /// # Support
255    /// All Android version.
256    #[deprecated = "Since Android 11, This does not function correctly due to android security."]
257    pub fn can_open_file(&self, uri: &FileUri) -> crate::Result<bool> {
258        on_android!({
259            impl_se!(struct Req<'a> { uri: &'a FileUri, mime_type: Option<&'a str> });
260            impl_de!(struct Res { value: bool });
261
262            let mime_type = None;
263
264            self.0.api
265                .run_mobile_plugin::<Res>("canViewFile", Req { uri, mime_type })
266                .map(|v| v.value)
267                .map_err(Into::into)
268        })
269    }
270
271    /// Determines whether the specified file can be used with [`FileSender::edit_file`].  
272    /// If no app is available to handle the file, this returns false. 
273    /// 
274    /// # Args
275    /// - ***uri*** :  
276    /// Target file URI.  
277    /// Must be **read-writeable**.  
278    /// 
279    /// # Support
280    /// All Android version.
281    #[deprecated = "Since Android 11, This does not function correctly due to android security."]
282    pub fn can_edit_file(&self, uri: &FileUri) -> crate::Result<bool> {
283        on_android!({
284            impl_se!(struct Req<'a> { uri: &'a FileUri, mime_type: Option<&'a str> });
285            impl_de!(struct Res { value: bool });
286
287            let mime_type = None;
288
289            self.0.api
290                .run_mobile_plugin::<Res>("canEditFile", Req { uri, mime_type })
291                .map(|v| v.value)
292                .map_err(Into::into)
293        })
294    }
295}