-
Notifications
You must be signed in to change notification settings - Fork 896
Expand file tree
/
Copy pathfile_picker.dart
More file actions
303 lines (294 loc) · 13.3 KB
/
Copy pathfile_picker.dart
File metadata and controls
303 lines (294 loc) · 13.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:file_picker/src/platform/file_picker_platform_interface.dart';
import 'package:file_picker/src/api/file_picker_result.dart';
import 'package:file_picker/src/api/platform_file.dart';
import 'package:file_picker/src/api/file_picker_types.dart';
import 'package:file_picker/src/api/android_saf_options.dart';
abstract final class FilePicker {
/// Retrieves the file(s) from the underlying platform
///
/// Default [type] set to [FileType.any] with [allowMultiple] set to `false`.
/// Optionally, [allowedExtensions] might be provided (e.g. `[pdf, svg, jpg]`.).
///
/// If [withData] is set, picked files will have its byte data immediately available on memory as `Uint8List`
/// which can be useful if you are picking it for server upload or similar. However, have in mind that
/// enabling this on IO (iOS & Android) may result in out of memory issues if you allow multiple picks or
/// pick huge files. Use [withReadStream] instead. Defaults to `true` on web, `false` otherwise.
/// Not supported on macOS.
///
/// If [withReadStream] is set, picked files will have its byte data available as a [Stream<List<int>>]
/// which can be useful for uploading and processing large files. Defaults to `false`.
/// Not supported on macOS.
///
/// If you want to track picking status, for example, because some files may take some time to be
/// cached (particularly those picked from cloud providers), you may want to set [onFileLoading] handler
/// that will give you the current status of picking.
/// Not supported on macOS.
///
/// If [lockParentWindow] is set, the child window (file picker window) will
/// stay in front of the Flutter window until it is closed (like a modal
/// window). This parameter works only on Windows desktop.
/// On macOS the parent window will be locked and this parameter is ignored.
///
/// [dialogTitle] can be optionally set on desktop platforms to set the modal window title.
/// Not supported on macOS. It will be ignored on other platforms.
///
/// [initialDirectory] can be optionally set to an absolute path to specify
/// where the dialog should open. Only supported on Linux, macOS, and Windows.
/// On macOS the home directory shortcut (~/) is not necessary and passing it will be ignored.
/// On macOS if the [initialDirectory] is invalid, the user directory or previously valid directory
/// will be used.
///
/// [readSequential] can be optionally set on web to keep the import file order during import.
/// Not supported on macOS.
///
/// [cancelUploadOnWindowBlur] prevents upload cancellation when window focus is lost.
/// Only supported on web.
///
/// The result is wrapped in a [FilePickerResult] which contains helper getters
/// with useful information regarding the picked [List<PlatformFile>].
///
/// For more information, check the [API documentation](https://github.com/miguelpruivo/flutter_file_picker/wiki/api).
///
/// Note: This requires the User Selected File Read entitlement on macOS.
///
/// Returns `null` if aborted.
/// selection; `pickFiles` now implies multiple selection by default.
/// NOTE: `withData`, `withReadStream` and `readSequential` are deprecated.
/// Call `PlatformFile.readAsBytes()` or `PlatformFile.readAsByteStream()` on
/// the returned `PlatformFile` to load data on demand. These parameters
/// will be removed in a future release.
static Future<FilePickerResult?> pickFiles({
String? dialogTitle,
String? initialDirectory,
FileType type = FileType.any,
List<String>? allowedExtensions,
Function(FilePickerStatus)? onFileLoading,
int compressionQuality = 0,
@Deprecated(
'use pickFile for single-file selection; this parameter will be removed in a future release',
)
bool allowMultiple = true,
@Deprecated(
'Use PlatformFile.readAsBytes(); this parameter will be removed in a future release',
)
bool withData = kIsWeb,
@Deprecated(
'Use PlatformFile.readAsByteStream(); this parameter will be removed in a future release',
)
bool withReadStream = false,
bool lockParentWindow = false,
@Deprecated(
'Use PlatformFile.readAsByteStream(); this parameter will be removed in a future release',
)
bool readSequential = false,
bool cancelUploadOnWindowBlur = true,
AndroidSAFOptions? androidSafOptions,
int? parentWindowHandle,
}) {
return FilePickerPlatform.instance.pickFiles(
dialogTitle: dialogTitle,
initialDirectory: initialDirectory,
type: type,
allowedExtensions: allowedExtensions,
onFileLoading: onFileLoading,
compressionQuality: compressionQuality,
allowMultiple: allowMultiple,
withData: withData,
withReadStream: withReadStream,
lockParentWindow: lockParentWindow,
readSequential: readSequential,
cancelUploadOnWindowBlur: cancelUploadOnWindowBlur,
androidSafOptions: androidSafOptions,
parentWindowHandle: parentWindowHandle,
);
}
/// Opens a native file explorer and lets the user select a single file.
///
/// This is a convenience wrapper around [pickFiles] for when you only need to
/// pick one file. It returns a [PlatformFile] directly, or `null` if the
/// user canceled the operation.
///
/// For documentation on the parameters, see [pickFiles].
static Future<PlatformFile?> pickFile({
String? dialogTitle,
String? initialDirectory,
FileType type = FileType.any,
List<String>? allowedExtensions,
Function(FilePickerStatus)? onFileLoading,
int compressionQuality = 0,
bool lockParentWindow = false,
bool cancelUploadOnWindowBlur = true,
AndroidSAFOptions? androidSafOptions,
}) async {
final result = await FilePickerPlatform.instance.pickFiles(
dialogTitle: dialogTitle,
initialDirectory: initialDirectory,
type: type,
allowedExtensions: allowedExtensions,
onFileLoading: onFileLoading,
compressionQuality: compressionQuality,
allowMultiple: false,
withData: false,
withReadStream: false,
lockParentWindow: lockParentWindow,
readSequential: false,
cancelUploadOnWindowBlur: cancelUploadOnWindowBlur,
androidSafOptions: androidSafOptions,
);
return result?.files.firstOrNull;
}
/// Displays a dialog that allows the user to select both files and
/// directories simultaneously, returning their absolute paths.
///
/// **Platform Support:** As of right now, this functionality is only
/// supported on macOS.
///
/// [initialDirectory] can be optionally set to an absolute path to specify
/// where the dialog should open. On macOS the home directory shortcut (~/) is
/// not necessary and passing it will be ignored. On macOS if the
/// [initialDirectory] is invalid the user directory or previously valid
/// directory will be used.
///
/// The file type filter [type] defaults to [FileType.any]. Optionally,
/// [allowedExtensions] might be provided (e.g. `["pdf", "svg", "jpg"]`).
///
/// Returns a [Future<List<String>?>] that resolves to a list of absolute
/// paths for the selected files and directories. If the user cancels the
/// dialog or if the paths cannot be resolved, the method returns `null`.
static Future<List<String>?> pickFileAndDirectoryPaths({
String? dialogTitle,
String? initialDirectory,
FileType type = FileType.any,
List<String>? allowedExtensions,
}) {
return FilePickerPlatform.instance.pickFileAndDirectoryPaths(
dialogTitle: dialogTitle,
initialDirectory: initialDirectory,
type: type,
allowedExtensions: allowedExtensions,
);
}
/// Asks the underlying platform to remove any temporary files created by this plugin.
///
/// This typically relates to cached files that are stored in the cache directory of
/// each platform and it isn't required to invoke this as the system should take care
/// of it whenever needed. However, this will force the cleanup if you want to manage those on your own.
///
/// This method is only available on mobile platforms (Android & iOS).
///
/// Returns `true` if the files were removed with success, `false` otherwise.
static Future<bool?> clearTemporaryFiles() {
return FilePickerPlatform.instance.clearTemporaryFiles();
}
/// Selects a directory and returns its absolute path.
///
/// On Android, this requires to be running on SDK 21 or above, else won't work.
/// Note: Some Android paths are protected, hence can't be accessed and will return `/` instead.
///
/// [dialogTitle] can be set to display a custom title on desktop platforms.
/// Not supported on macOS. It will be ignored on other platforms.
///
/// If [lockParentWindow] is set, the child window (file picker window) will
/// stay in front of the Flutter window until it is closed (like a modal
/// window). This parameter works only on Windows desktop.
/// On macOS the parent window will be locked and this parameter is ignored.
///
/// [initialDirectory] can be optionally set to an absolute path to specify
/// where the dialog should open. Only supported on Linux, macOS, and Windows.
/// On macOS the home directory shortcut (~/) is not necessary and passing it will be ignored.
/// On macOS if the [initialDirectory] is invalid, the user directory or previously valid directory
/// will be used.
///
/// Returns a [Future<String?>] which resolves to the absolute path of the selected directory,
/// if the user selected a directory. Returns `null` if the user aborted the dialog or if the
/// folder path couldn't be resolved.
///
/// Note: on Windows, throws a `WindowsException` with a detailed error message, if the dialog
/// could not be instantiated or the dialog result could not be interpreted.
/// Note: Some Android paths are protected, hence can't be accessed and will return `/` instead.
/// Note: The User Selected File Read entitlement is required on macOS.
/// Note: On Android, if [androidSafOptions] is provided, the returned string will be a
/// `content://` document tree URI instead of an absolute path.
static Future<String?> getDirectoryPath({
String? dialogTitle,
bool lockParentWindow = false,
String? initialDirectory,
AndroidSAFOptions? androidSafOptions,
int? parentWindowHandle,
}) {
return FilePickerPlatform.instance.getDirectoryPath(
dialogTitle: dialogTitle,
lockParentWindow: lockParentWindow,
initialDirectory: initialDirectory,
androidSafOptions: androidSafOptions,
parentWindowHandle: parentWindowHandle,
);
}
/// Opens a save file dialog to let the user select a location and a file name to
/// save [bytes] to.
///
/// Returns a [Future<String?>] which resolves to the absolute path of the
/// saved file, or `null` if the user canceled the operation.
///
/// On the web, this starts a download and always returns `null`.
///
/// The User Selected File Read/Write entitlement is required on macOS.
///
/// [dialogTitle] can be set to display a custom title on desktop platforms.
/// Not supported on macOS.
///
/// [fileName] should be set to provide a default file name.
/// Throws an `IllegalCharacterInFileNameException` under Windows if the
/// given [fileName] contains forbidden characters.
///
/// [initialDirectory] can be optionally set to an absolute path to specify
/// where the dialog should open. Only supported on Linux, macOS, and Windows.
/// On macOS the home directory shortcut (~/) is not necessary and passing it will be ignored.
/// On macOS if the [initialDirectory] is invalid, the user directory or previously valid directory
/// will be used.
///
/// The file type filter [type] defaults to [FileType.any]. Optionally,
/// [allowedExtensions] might be provided (e.g. `[pdf, svg, jpg]`). Both
/// parameters are just a proposal to the user as the save file dialog does
/// not enforce these restrictions.
///
/// If [lockParentWindow] is set, the child window (file picker window) will
/// stay in front of the Flutter window until it is closed (like a modal
/// window). This parameter works only on Windows desktop.
///
/// Returns `null` if aborted.
static Future<String?> saveFile({
String? dialogTitle,
required String fileName,
String? initialDirectory,
FileType type = FileType.any,
List<String>? allowedExtensions,
required Uint8List bytes,
Function(FilePickerStatus)? onFileLoading,
bool lockParentWindow = false,
int? parentWindowHandle,
}) {
return FilePickerPlatform.instance.saveFile(
dialogTitle: dialogTitle,
fileName: fileName,
initialDirectory: initialDirectory,
type: type,
allowedExtensions: allowedExtensions,
bytes: bytes,
onFileLoading: onFileLoading,
lockParentWindow: lockParentWindow,
parentWindowHandle: parentWindowHandle,
);
}
/// Skips the entitlements checks on macOS, allowing the plugin to be used without Sandbox enabled.
///
/// This is only relevant for macOS. On other platforms, this method does nothing.
/// Call this method before any other file picking method to ensure that the entitlements checks are skipped.
///
/// Note: Skipping entitlements checks may lead to unexpected behavior or security issues. Use with caution.
static Future<void> skipEntitlementsChecks() {
return FilePickerPlatform.instance.skipEntitlementsChecks();
}
}