【问题标题】:Download pdf from url, save to phones local storage in android in flutter从url下载pdf,在flutter中保存到android中的手机本地存储
【发布时间】:2020-08-13 11:50:42
【问题描述】:

我正在做一个项目,一旦点击按钮,我需要从 URL 下载 pdf 文件,并将其存储到手机存储中(可能是下载文件夹)。

关于如何做到这一点的任何想法?正在下载的文件也不总是相同的,可以是从 pdf 到图像的任何文件。

【问题讨论】:

  • 提前致谢!!
  • 你可以使用像cropper这样的图像裁剪器

标签: android api flutter


【解决方案1】:

您可以使用Dio 包将文件下载到本地存储,使用Dio().download

response = await dio.download("https://www.google.com/", "./xx.html");

您也可以查看open source project 作为参考

【讨论】:

  • 是否有可能“Dio”链接无意中指向了与开源项目相同的站点?如果是这样的话,可以在pub.dev/packages/dio 找到 Dio
  • 哦,是的!纠正了这一点。谢谢指出
  • 我使用了 dio.download 并检查了它是否保存在设备中。它正确保存,但我没有收到任何消息,它不在下载中,然后仅在目录中归档。您是如何将通知视为已保存文件的?你是手动做的吗?
【解决方案2】:

以下代码适用于 iOS 和 Android。如果您要下载图片,请将“.pdf”替换为“.jpg”。

pubspec.yaml中,将以下代码粘贴到依赖项下

dio: any
path_provider: any
file_utils: any
permission_handler: any

android/app/src/main/AndroidManifest.xml 中,将下面的行粘贴到<application> 标记之外

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

下面是代码:

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:async';
import 'package:file_utils/file_utils.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:intl/intl.dart';

void main() => runApp(Downloader());

class Downloader extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(
    title: "File Downloader",
    debugShowCheckedModeBanner: false,
    home: FileDownloader(),
    theme: ThemeData(primarySwatch: Colors.blue),
  );
}

class FileDownloader extends StatefulWidget {
  @override
  _FileDownloaderState createState() => _FileDownloaderState();
}

class _FileDownloaderState extends State<FileDownloader> {

final pdfUrl = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";
  
  bool downloading = false;
  var progress = "";
  var path = "No Data";
  var platformVersion = "Unknown";
  var _onPressed;
  Directory externalDir;

  @override
  void initState() {
    super.initState();
    downloadFile();
  }

String convertCurrentDateTimeToString() {
    String formattedDateTime =
    DateFormat('yyyyMMdd_kkmmss').format(DateTime.now()).toString();
    return formattedDateTime;
  }

  Future<void> downloadFile() async {
    Dio dio = Dio();
    

    final status = await Permission.storage.request();
    if (status.isGranted) {
      String dirloc = "";
      if (Platform.isAndroid) {
        dirloc = "/sdcard/download/";
      } else {
        dirloc = (await getApplicationDocumentsDirectory()).path;
      }

      try {
        FileUtils.mkdir([dirloc]);
        await dio.download(pdfUrl, dirloc + convertCurrentDateTimeToString() + ".pdf",
            onReceiveProgress: (receivedBytes, totalBytes) {
          print('here 1');
              setState(() {
                downloading = true;
                progress = ((receivedBytes / totalBytes) * 100).toStringAsFixed(0) + "%";
                print(progress);
              });
              print('here 2');
            });
      } catch (e) {
        print('catch catch catch');
        print(e);
      }

      setState(() {
        downloading = false;
        progress = "Download Completed.";
        path = dirloc + convertCurrentDateTimeToString() + ".pdf";
      });
      print(path);
      print('here give alert-->completed');
    } else {
      setState(() {
        progress = "Permission Denied!";
        _onPressed = () {
          downloadFile();
        };
      });
    }
  }

  @override
  Widget build(BuildContext context) => Scaffold(
      appBar: AppBar(
        title: Text('File Downloader'),
      ),
      body: Center(
          child: downloading
              ? Container(
            height: 120.0,
            width: 200.0,
            child: Card(
              color: Colors.black,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  CircularProgressIndicator(),
                  SizedBox(
                    height: 10.0,
                  ),
                  Text(
                    'Downloading File: $progress',
                    style: TextStyle(color: Colors.white),
                  ),
                ],
              ),
            ),
          )
              : Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(path),
              MaterialButton(
                child: Text('Request Permission Again.'),
                onPressed: _onPressed,
                disabledColor: Colors.blueGrey,
                color: Colors.pink,
                textColor: Colors.white,
                height: 40.0,
                minWidth: 100.0,
              ),
            ],
          )));
}

【讨论】:

    【解决方案3】:

    我希望这会对你有所帮助。检查文件是否已经存在,如果没有,则使用 URL 获取文件并将其保存在应用程序目录中。

    Future<File> createFile() async {
        try {
          /// setting filename 
          final filename = widget.docPath;
    
          /// getting application doc directory's path in dir variable
          String dir = (await getApplicationDocumentsDirectory()).path;
    
          /// if `filename` File exists in local system then return that file.
          /// This is the fastest among all.
          if (await File('$dir/$filename').exists()) return File('$dir/$filename');
    
          ///if file not present in local system then fetch it from server
    
          String url = widget.documentUrl;
    
          /// requesting http to get url
          var request = await HttpClient().getUrl(Uri.parse(url));
    
          /// closing request and getting response
          var response = await request.close();
    
          /// getting response data in bytes
          var bytes = await consolidateHttpClientResponseBytes(response);
    
          /// generating a local system file with name as 'filename' and path as '$dir/$filename'
          File file = new File('$dir/$filename');
    
          /// writing bytes data of response in the file.
          await file.writeAsBytes(bytes);
    
          /// returning file.
          return file;
        }
    
        /// on catching Exception return null
        catch (err) {
          errorMessage = "Error";
          print(errorMessage);
          print(err);
          return null;
        }
      }
    

    【讨论】:

    • 我希望在下载完成时使用确定按钮弹出一个弹出窗口,然后单击确定打开下载的文件
    • 这个函数正在返回一个文件,你可以等待future完成,在你得到文件后只需使用AlertDialog显示弹出窗口。
    猜你喜欢
    • 2019-06-09
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 2012-01-23
    • 2019-10-08
    • 2019-05-26
    • 2018-07-04
    相关资源
    最近更新 更多