「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战」。
本文翻译自:
file_picker | Flutter Package (flutter-io.cn)
Installation · miguelpruivo/flutter_file_picker Wiki · GitHub
Setup · miguelpruivo/flutter_file_picker Wiki · GitHub
译时版本: file_picker 4.3.3
File Picker
允许使用原生文件浏览器选取单个或多个文件,支持扩展名过滤。
现在支持的特性
- 使用操作系统默认的原生选取器
- 支持多平台 (移动端、 Web 、 桌面端 和 go-flutter)
- 使用自定义格式过滤器选取文件 - 你可以提供一个文件扩展名列表(pdf、 svg、 zip、等)。
- 从云文件选取 (GDrive、 Dropbox、 iCloud)
- 选取单个或多个文件
- 不同的默认类型的过滤器(多媒体、图像、视频、音频或其它任何类型)
- 选取目录
- 如果需要可直接将文件加载到内存 (
Uint8List)中; - 打开一个 保存文件 / 另存为 对话框(对话框允许用户指定驱动器、目录和文件名来保存文件)
如果你想在该饮中看到某个特性,可自由提出建议。🎉
安装
将最新版本的 file_picker 依赖添加到 pubspec.yaml 文件中。
配置
Android
万事俱备,只要承认了运行时权限(包括插件),就准备好了!
也是不久之前,因为添加了对 Android 11 的兼容,你可能想要确认是在使用 可共存的 gradle 版本之一或者你可能会遇到编译问题,如 <query> 标签未被识别。
对于发布的编译,需要去掉 androidx.lifecycle.DefaultLifecycleObserver 防止混乱。可以在 android/app 文件夹下添加名为 proguard-rules.pro 的文件,并且加上以下规则:-keep class androidx.lifecycle.DefaultLifecycleObserver 来实现。
注意: 如果是在覆写 MainActivity 的 onActivityResult,确保调用了 super.onActivityResult(...) 用于未处理的 activity 。否则选取文件会失败且没有任何错误信息。
iOS
由于 1.7.0 的子依赖, 需要添加 use_frameworks! 到 <project root>/ios/Podfile 中。
target 'Runner' do
use_frameworks!
可选的权限
根据你想选取路径的文件的位置,可能需要添加一些 key 到 iOS 应用的 Info.plist 文件中,位于 <project root>/ios/Runner/Info.plist :
-
UIBackgroundModes 带有 fetch 和 remote-notifications key - 如果要使用
FileType.any或FileType.custom,该设置是必需的。描述应用需要访问后台任务的原因,例如下载文件(从云服务)。这称作 Required background modes (需要后台模式),在 IDE 中分别是 key App download content from network 和 App downloads content in response to push notifications (因为实际上两种方法没有被覆写,不添加这个 property/key ,不会显示警告,但是不应该阻止它的正确用法。)。<key>UIBackgroundModes</key> <array> <string>fetch</string> <string>remote-notification</string> </array> -
NSAppleMusicUsageDescription - 如果要使用
FileType.audio, 该设置是必需的。描述应用需要音乐库权限的原因。在 IDE 中是 Privacy - Media Library Usage Description 。<key>NSAppleMusicUsageDescription</key> <string>Explain why your app uses music</string> -
UISupportsDocumentBrowser - 如果要直接对目录进行写操作,该设置是必需的。通过这种方式,iOS 为应用和用户创建应用文件夹,用户在该文件夹中创建和选取目录,并且应用也有权限在此文件夹中进行写操作。
<key>UISupportsDocumentBrowser</key> <true/> -
LSSupportsOpeningDocumentsInPlace - 如果想要打开原始文件,而不是缓存文件(使用
FileType.all时),该设置是必需的。<key>LSSupportsOpeningDocumentsInPlace</key> <true/> -
NSPhotoLibraryUsageDescription - 如果在在使用
FileType.image或FileType.video。描述应用需要相册权限的理由。在 IDE 中是 Privacy - Photo Library Usage Description 。<key>NSPhotoLibraryUsageDescription</key> <string>Explain why your app uses photo library</string>
注意: 低于 11.0 的任意 iOS 版本,会需要 Apple 开发者帐户使 CloudKit 可用,和使用文档选取器(当选取 FileType.all 、 FileType.custom 或者带 getMultiFilePath() 的其它任何选项)成为可能。可以在这里 了解更多内容。
Web
已安装 Flutter 2.0 或更高版本的话,就可以了。
桌面端
从 v4.0.0 开始该包支持所有的平台(Linux 、 macOS 和 Windows)。新的实现完全使用 Dart 编写。它代替了用 Go 编写需要 go-flutter 的旧实现。要在 macOS、 Linux 和 Windows 上使用,需要使桌面平台开发可用,取决于你想支持的操作系统:
$ flutter config --enable-windows-desktop
$ flutter config --enable-macos-desktop
$ flutter config --enable-linux-desktop
可以在这里了解更多内容。
桌面端(go-flutter)(不推荐)
此用法需要使用 Go 。 由于已不推荐,所以未翻译。
需要者可参考原文
用法
快速简单的用法示例:
单个文件
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path);
} else {
// User canceled the picker
}
多个文件
FilePickerResult? result = await FilePicker.platform.pickFiles(allowMultiple: true);
if (result != null) {
List<File> files = result.paths.map((path) => File(path)).toList();
} else {
// User canceled the picker
}
多个文件带扩展名过滤
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'pdf', 'doc'],
);
选取目录
String? selectedDirectory = await FilePicker.platform.getDirectoryPath();
if (selectedDirectory == null) {
// User canceled the picker
}
保存文件 / 另存为 对话框
String? outputFile = await FilePicker.platform.saveFile(
dialogTitle: 'Please select an output file:',
fileName: 'output-file.pdf',
);
if (outputFile == null) {
// User canceled the picker
}
加载结果和文件详情
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
PlatformFile file = result.files.first;
print(file.name);
print(file.bytes);
print(file.size);
print(file.extension);
print(file.path);
} else {
// User canceled the picker
}
在 Flutter Web 上选取并上传一个文件到 Firebase 存储
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
Uint8List fileBytes = result.files.first.bytes;
String fileName = result.files.first.name;
// Upload file
await FirebaseStorage.instance.ref('uploads/$fileName').putData(fileBytes);
}
完整的用法详细参考 Wiki 。
示例应用
flutter_file_picker/file_picker_demo.dart at master · miguelpruivo/flutter_file_picker · GitHub