Hi, welcome back! In this tutorial, I'll show you how you can download files in your flutter app using Dio package. We are going to store the downloaded file in the ApplicationDirectory using the path_provider package.
Before showing you the code, let me show what exactly we are going to achieve by the end of this tutorial.
STEPS TO REPRODUCE:
- Add the package dependencies to your pubspec.yaml file
dependencies:
flutter:
sdk: flutter
dio: any
path_provider: any
- Use the following code in your main.dart file to achieve results as shown in the video. (Don't miss the comments in the code to understand better)
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'File Download',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'File Download With Progress'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool downloading = false;
String progress = '0';
bool isDownloaded = false;
String uri =
'https://file-examples.com/wp-content/uploads/2017/10/file-example_PDF_1MB.pdf'; // url of the file to be downloaded
String filename = 'test.pdf'; // file name that you desire to keep
// downloading logic is handled by this method
Future<void> downloadFile(uri, fileName) async {
setState(() {
downloading = true;
});
String savePath = await getFilePath(fileName);
Dio dio = Dio();
dio.download(
uri,
savePath,
onReceiveProgress: (rcv, total) {
print(
'received: ${rcv.toStringAsFixed(0)} out of total: ${total.toStringAsFixed(0)}');
setState(() {
progress = ((rcv / total) * 100).toStringAsFixed(0);
});
if (progress == '100') {
setState(() {
isDownloaded = true;
});
} else if (double.parse(progress) < 100) {}
},
deleteOnError: true,
).then((_) {
setState(() {
if (progress == '100') {
isDownloaded = true;
}
downloading = false;
});
});
}
//gets the applicationDirectory and path for the to-be downloaded file
// which will be used to save the file to that path in the downloadFile method
Future<String> getFilePath(uniqueFileName) async {
String path = '';
Directory dir = await getApplicationDocumentsDirectory();
path = '${dir.path}/$uniqueFileName.pdf';
return path;
}
@override
Widget build(BuildContext context) {
print('build running');
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('$progress%'),
isDownloaded
? Text(
'File Downloaded! You can see your file in the application\'s directory',
)
: Text(
'Click the FloatingActionButton to start Downloading!'),
],
),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.play_arrow),
onPressed: () async {
downloadFile(uri, filename);
}),
);
}
}
I hope you liked the example! Keep Fluttering and I welcome any doubts in the comments!