Flutter 中怎么下载文件

admin2024-06-11  32

原文链接:How to download files in a flutter. - 原文作者 Dipali Thakare

本文采用意译的方式


Flutter 中怎么下载文件,Flutter 中怎么下载文件_ide,第1张

本文将演示在 Flutter 应用中,怎么从网上下载文件。我们可以下载任何类型的文件,并将其存储到指定位置。有很多种方法实现,比如很受欢迎的包 flutter download 可以用来实现。然而,我们将会以最简单的方式来演示。

今天,我们将学习怎么将网络上的文件下载下来,并展示一个进度条。

首先,我们需要添加 Flutter 包 dio,permission_handler 和 path_provider 到我们的项目,在 pubspec.yaml 文件中添加下面的内容。

dio: any
  permission_handler: any
  path_provider: any

AndroidManifest.xml 文件中添加读和写的允许:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

并且,在 AndroidManifest.xml 文件中添加 <application>

<application
   android:requestLegacyExternalStorage="true"

首先,创建一个 FileDownload.dart 文件。_startDownloading 方法将会创建一个文件,该文件的路径由 _getFilePath 方法返回。在安卓中,我们可以在下载的文件夹中看到这个文件。

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";
  }
}

下载进度对话框:

下面是进度对话框的代码。当下载一个文件时候,进度对话框会显示,用于展示下载的进度。

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 文件中,我们已经实现了一个带有下载按钮的简单代码。当点击下载按钮,我们会请求许可。一旦许可被通过,我们将可以下载文件。

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 中怎么下载文件,Flutter 中怎么下载文件_ide_02,第2张

初始化下载按钮


Flutter 中怎么下载文件,Flutter 中怎么下载文件_前端_03,第3张

当触发下载按钮,则调出文件下载进度的弹窗

希望这篇文件能够帮到你们用 flutter 从网上下载文件。

谢谢阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!