从url下载pdf,在flutter中保存到android中的手机本地存储
Posted
技术标签:
【中文标题】从url下载pdf,在flutter中保存到android中的手机本地存储【英文标题】:Download pdf from url, save to phones local storage in android in flutter 【发布时间】:2020-08-13 11:50:42 【问题描述】:我正在做一个项目,一旦点击按钮,我需要从 URL 下载 pdf 文件,并将其存储到手机存储中(可能是下载文件夹)。
关于如何做到这一点的任何想法?正在下载的文件也不总是相同的,可以是从 pdf 到图像的任何文件。
【问题讨论】:
提前致谢!! 你可以使用像cropper这样的图像裁剪器 【参考方案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
显示弹出窗口。以上是关于从url下载pdf,在flutter中保存到android中的手机本地存储的主要内容,如果未能解决你的问题,请参考以下文章