我正在使用Flutter 1.10.3构建应用程序,并且在将图像下载到设备的Downloads文件夹时遇到困难。
是否可以选择不使用任何第3部分库?
答案 0 :(得分:4)
如果您控制服务器,另一种选择是让用户的系统处理下载。在服务器上,您向响应添加 Content-Disposition: attachment
标头。在 nginx 中,您可以使用启用站点的配置文件中的 add_header
指令执行此操作:
add_header Content-Disposition "attachment";
关于here的更多说明。
然后在 Flutter 端你可以使用 url_launcher 包来启动下载:
await launch('https://www.example.com/my_file.pdf');
这会将下载交给手机上安装的浏览器。 Content-Disposition: attachment
标头会告诉浏览器它是要下载的,而不是显示或播放的。
这个解决方案非常简单,但它不能让您控制文件下载到的位置。
答案 1 :(得分:2)
添加一些必需的依赖项,我仅使用android进行测试演示。在iOS设备中实施时,请检查file_utils
和path_provider
。
dio: ^3.0.0
path_provider: ^1.3.0
simple_permissions: ^0.1.9
file_utils: ^0.1.3
您需要在android mainfest文件上添加权限。
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_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:simple_permissions/simple_permissions.dart';
import 'package:file_utils/file_utils.dart';
import 'dart:math';
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 imgUrl = "https://images6.alphacoders.com/683/thumb-1920-683023.jpg";
bool downloading = false;
var progress = "";
var path = "No Data";
var platformVersion = "Unknown";
Permission permission1 = Permission.WriteExternalStorage;
var _onPressed;
static final Random random = Random();
Directory externalDir;
@override
void initState() {
super.initState();
downloadFile();
}
Future<void> downloadFile() async {
Dio dio = Dio();
bool checkPermission1 =
await SimplePermissions.checkPermission(permission1);
// print(checkPermission1);
if (checkPermission1 == false) {
await SimplePermissions.requestPermission(permission1);
checkPermission1 = await SimplePermissions.checkPermission(permission1);
}
if (checkPermission1 == true) {
String dirloc = "";
if (Platform.isAndroid) {
dirloc = "/sdcard/download/";
} else {
dirloc = (await getApplicationDocumentsDirectory()).path;
}
var randid = random.nextInt(10000);
try {
FileUtils.mkdir([dirloc]);
await dio.download(imgUrl, dirloc + randid.toString() + ".jpg",
onReceiveProgress: (receivedBytes, totalBytes) {
setState(() {
downloading = true;
progress =
((receivedBytes / totalBytes) * 100).toStringAsFixed(0) + "%";
});
});
} catch (e) {
print(e);
}
setState(() {
downloading = false;
progress = "Download Completed.";
path = dirloc + randid.toString() + ".jpg";
});
} 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,
),
],
)));
}
答案 2 :(得分:0)