原文链接:How to download files in a flutter. - 原文作者 Dipali Thakare
本文采用意译的方式
本文将演示在 Flutter
应用中,怎么从网上下载文件。我们可以下载任何类型的文件,并将其存储到指定位置。有很多种方法实现,比如很受欢迎的包 flutter download 可以用来实现。然而,我们将会以最简单的方式来演示。
今天,我们将学习怎么将网络上的文件下载下来,并展示一个进度条。
首先,我们需要添加 Flutter
包 dio,permission_handler 和 path_provider 到我们的项目,在 pubspec.yaml
文件中添加下面的内容。
yaml
dio: any
permission_handler: any
path_provider: any
在 AndroidManifest.xml 文件中添加读和写的允许:
xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
并且,在 AndroidManifest.xml 文件中添加 <application>
这个标签:
xml
<application
android:requestLegacyExternalStorage="true"
首先,创建一个 FileDownload.dart
文件。_startDownloading 方法将会创建一个文件,该文件的路径由 _getFilePath 方法返回。在安卓中,我们可以在下载的文件夹中看到这个文件。
dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
class FileDownload {
Dio dio = Dio();
bool isSuccess = false;
void _startDownloading(BuildContext context, final Function okCallback) async {
String fileName = "Sample.pdf"; // 设定下载文件的名称
String baseUrl =
"https://file-examples.com/wp-content/uploads/2017/10/file-example_PDF_1MB.pdf"; // 远程文件路径
String path = await _getFilePath(fileName); // 获取存储在本地的路径
try {
await dio.download(
baseUrl,
path,
onReceiveProgress: (recivedBytes, totalBytes) {
okCallback(recivedBytes, totalBytes);
},
deleteOnError: true,
).then((_) {
isSuccess = true;
});
} catch (e) {
print("Exception$e");
}
if (isSuccess) {
Navigator.pop(context);
}
}
Future<String> _getFilePath(String filename) async {
Directory? dir;
try {
if (Platform.isIOS) {
dir = await getApplicationDocumentsDirectory(); // 针对 iOS
} else {
dir = Directory('/storage/emulated/0/Download/'); // 针对 android
if (!await dir.exists()) dir = (await getExternalStorageDirectory())!;
}
} catch (err) {
print("Cannot get download folder path $err");
}
return "${dir?.path}$filename";
}
}
下载进度对话框:
下面是进度对话框的代码。当下载一个文件时候,进度对话框会显示,用于展示下载的进度。
dart
import 'package:flutter/material.dart';
import 'package:flutter_downloading_file/download_file.dart';
class DownloadProgressDialog extends StatefulWidget {
@override
State<DownloadProgressDialog> createState() => _DownloadProgressDialogState();
}
class _DownloadProgressDialogState extends State<DownloadProgressDialog> {
double progress = 0.0; // 当前进度
@override
void initState() {
_startDownload(); // 开始下载
super.initState();
}
void _startDownload() {
FileDownload().startDownloading(context, (recivedBytes, totalBytes) {
setState(() {
progress = recivedBytes / totalBytes; // 接收到的字节 / 文件总的字节
});
});
}
@override
Widget build(BuildContext context) {
String downloadingProgress = (progress * 100).toInt().toString();
return AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.symmetric(vertical: 10),
child: const Text(
"Downloading",
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
),
LinearProgressIndicator( // 展示当前的下载进度
value: progress,
backgroundColor: Colors.grey,
color: Colors.green,
minHeight: 10,
),
Align(
alignment: Alignment.bottomRight,
child: Text(
"$downloadingProgress %",
),
)
],
));
}
}
在我们的 main.dart
文件中,使用下面的代码。
在 main.dart
文件中,我们已经实现了一个带有下载按钮的简单代码。当点击下载按钮,我们会请求许可。一旦许可被通过,我们将可以下载文件。
dart
import 'package:flutter/material.dart';
import 'package:flutter_downloading_file/dowload_progress.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blueGrey,
),
home: const MyHomePage(),
));
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
super.key,
});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Download file in flutter"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async { // 点击下载按钮
bool result = await _permissionRequest();
if (result) { // 可以下载,则展示对话框
showDialog(
context: context,
builder: (dialogcontext) {
return DownloadProgressDialog();
});
} else {
print("No permission to read and write.");
}
},
child: const Text("Download File"))
],
),
),
);
}
// 是否允许请求
static Future<bool> _permissionRequest() async {
PermissionStatus result;
result = await Permission.storage.request();
if (result.isGranted) {
return true;
} else {
return false;
}
}
}
一旦文件被下载了,它可以被使用 open_filex包打开。这个包允许我们打开任何类型的文件。
输出:
初始化下载按钮
当触发下载按钮,则调出文件下载进度的弹窗
希望这篇文件能够帮到你们用 flutter
从网上下载文件。
谢谢阅读!