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