Flutter文件下载至下载文件夹插件downloadsfolder的使用
Flutter文件下载至下载文件夹插件downloadsfolder的使用
Flutter Download Folder Plugin 是一个用于获取不同平台上的下载文件夹路径,并执行与文件下载相关的操作的插件。
支持平台
平台 | 支持版本 |
---|---|
Android | SDK 20+ |
iOS | iOS 12+ |
Windows | ✅ |
macOS | ✅ |
Linux | ✅ |
插件功能介绍
获取下载目录路径
getDownloadDirectoryPath
函数通过平台特定的通道来获取当前平台的下载文件夹路径。
将文件复制到下载文件夹
copyFileIntoDownloadFolder
函数允许将文件复制到下载文件夹中,指定文件名并确保名称唯一以避免覆盖现有文件。
打开下载文件夹
openDownloadFolder
函数根据平台差异打开设备的下载文件夹。对于Android和iOS,它使用平台特定的通道;对于macOS和Windows,则是获取下载文件夹的路径后进行打开操作。
安装配置
在 pubspec.yaml
文件中添加 downloadsfolder
依赖:
dependencies:
downloadsfolder: ^1.1.0
配置项
Android
- 对于API 29及以上版本的Android设备,
copyFileIntoDownloadFolder
方法会使用MediaStore保存文件以绕过存储权限限制。 - 对于API 28及以下版本的设备,请确保已在
AndroidManifest.xml
中的应用元素下添加了WRITE_EXTERNAL_STORAGE
权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28"/>
iOS
为了启用 openDownloadFolder
功能,需要在 Info.plist
文件中添加如下键值对:
<key>UISupportsDocumentBrowser</key>
<true/>
macOS
进入项目文件夹下的 macOS/Runner/DebugProfile.entitlements
文件(对于发布版则为 'YOUR_PROJECT_NAME'Profile.entitlements
),并添加以下键:
<key>com.apple.security.files.downloads.read-write</key>
<true/>
使用示例代码
下面是一个完整的演示demo,展示了如何使用这个插件的功能:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:downloadsfolder/downloadsfolder.dart';
import 'package:file_picker/file_picker.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(const MyExample());
}
class MyExample extends StatelessWidget {
const MyExample({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyApp(),
);
}
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String? _downloadsfolderPath;
File? _pickedFile;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Column(
children: [
ElevatedButton(
onPressed: _getDownloadPath,
child: const Center(
child: Text('Get Download Path'),
),
),
if (_downloadsfolderPath != null)
Center(
child: Text('Downloads Folder Path: $_downloadsfolderPath\n'),
),
ElevatedButton(
onPressed: _pickAFile,
child: const Center(
child: Text('Pick a File'),
),
),
if (_pickedFile != null)
Center(
child: Text('Picked File Path: ${_pickedFile!.path}\n'),
),
if (_pickedFile != null)
ElevatedButton(
onPressed: _saveFile,
child: const Center(
child: Text('Save Picked File into Downloads Folder'),
),
),
ElevatedButton(
onPressed: _openDownloadFolder,
child: const Center(
child: Text('Show Download Folder'),
),
),
],
),
);
}
Future<void> _getDownloadPath() async {
Directory downloadsfolderPath;
try {
downloadsfolderPath = await getDownloadDirectory();
if (!mounted) return;
setState(() {
_downloadsfolderPath = downloadsfolderPath.path;
});
} on PlatformException {
if (!mounted) return;
setState(() {
_downloadsfolderPath = 'Failed to get folder path.';
});
}
}
Future<void> _pickAFile() async {
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (!mounted) return;
if (result != null) {
File file = File(result.files.single.path!);
setState(() {
_pickedFile = file;
});
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('No File Has been selected'),
),
);
}
}
Future<void> _saveFile() async {
bool storagePermissionGranted = true;
if (Platform.isAndroid || Platform.isIOS) {
storagePermissionGranted = await Permission.storage.isGranted;
if (!storagePermissionGranted) {
final status = await Permission.storage.request();
storagePermissionGranted = status.isGranted;
}
}
if (!storagePermissionGranted) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Failed to copy file. Storage permission is required.'),
),
);
return;
}
bool? success = await copyFileIntoDownloadFolder(
_pickedFile!.path,
basenameWithoutExtension(_pickedFile!.path),
desiredExtension: extension(_pickedFile!.path),
);
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(success == true ? 'File copied successfully.' : 'Failed to copy file.'),
action: success == true
? SnackBarAction(
label: 'Show Download Folder',
onPressed: _openDownloadFolder,
)
: null,
),
);
}
Future<void> _openDownloadFolder() => openDownloadFolder();
}
这段代码创建了一个简单的Flutter应用程序界面,用户可以点击按钮获取下载文件夹路径、选择文件、将所选文件保存到下载文件夹以及显示下载文件夹。
更多关于Flutter文件下载至下载文件夹插件downloadsfolder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter文件下载至下载文件夹插件downloadsfolder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,我可以为你提供一个关于如何使用 downloads_folder
插件在 Flutter 中将文件下载到下载文件夹的示例代码。这个插件可以帮助你轻松地将文件保存到设备的下载目录中。
首先,你需要在 pubspec.yaml
文件中添加 downloads_folder
依赖:
dependencies:
flutter:
sdk: flutter
downloads_folder: ^x.y.z # 请替换为最新版本号
然后运行 flutter pub get
来获取依赖。
接下来,在你的 Flutter 项目中,你可以使用以下代码来下载文件并将其保存到下载文件夹:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:downloads_folder/downloads_folder.dart';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('File Download Example'),
),
body: Center(
child: ElevatedButton(
onPressed: _downloadFile,
child: Text('Download File'),
),
),
),
);
}
}
Future<void> _downloadFile() async {
// 要下载的文件URL
final String fileUrl = 'https://example.com/path/to/your/file.pdf';
// 下载后的文件名
final String fileName = 'downloaded_file.pdf';
try {
// 获取下载目录路径
final Directory downloadsDirectory = await DownloadsFolder().getDownloadsDirectory();
final String filePath = '${downloadsDirectory.path}/$fileName';
// 创建文件引用
final File file = File(filePath);
// 使用http包下载文件
final http.Response response = await http.get(Uri.parse(fileUrl));
// 将下载的数据写入文件
await file.writeAsBytes(response.bodyBytes);
// 提示用户下载成功
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('File downloaded successfully to Downloads folder'),
),
);
} catch (e) {
// 提示用户下载失败
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Failed to download file: $e'),
backgroundColor: Colors.red,
),
);
}
}
代码解释:
-
依赖导入:
downloads_folder
:用于获取下载目录路径。path_provider
:虽然在这个示例中未直接使用,但通常用于获取应用目录路径(这个示例中我们用不到它,但有时候会有用)。http
:用于发送HTTP请求下载文件。
-
主应用:
MyApp
:根Widget,包含一个按钮,点击按钮调用_downloadFile
函数。
-
文件下载函数:
_downloadFile
:这个函数首先获取下载目录的路径,然后创建一个文件引用,接着使用http
包发送GET请求下载文件,最后将下载的数据写入文件。
-
错误处理:
- 使用
try-catch
块捕获并处理任何可能的异常,通过SnackBar向用户显示下载成功或失败的消息。
- 使用
请注意,你需要确保 AndroidManifest.xml
和 Info.plist
中有适当的权限声明,以允许应用访问存储。对于Android,通常需要 WRITE_EXTERNAL_STORAGE
权限(从Android 10开始,Scoped Storage生效,你可能需要请求 MANAGE_EXTERNAL_STORAGE
或使用MediaStore API,但 downloads_folder
插件通常会处理这些细节)。对于iOS,你需要确保应用有权限写入文件。
希望这个示例能帮助你理解如何使用 downloads_folder
插件在Flutter应用中下载文件到下载文件夹。