Flutter Web download file from url instead of opening it - flutter

Is there any way to get files like .pdf downloaded directly on user's device instead of opening this pdf in the browser?
This code works for downloading non browser supported files but it opens pdf, mp3, etc. in the browser.
final anchor = AnchorElement(
href: pickedFile)
..setAttribute("download", fileName)
..click();

If someone is still searching for solution.Here is what I have done.
Anchor tag will directly download file if it has download attribute.
Note: Download attribute is only supported for same-origin request
So instead of assigning external URL link to anchor element. Create Blob object from PDF data and create Object URL from that.
var url = Url.createObjectUrlFromBlob(Blob([data]));
AnchorElement(href: url)
..setAttribute('download', '<downloaded_file_name.pdf>')
..click();
I am using Firebase to store file so here is the complete code.
FirebaseStorage.instance.ref(resumeFileName).getData().then(
(data) {
var url = Url.createObjectUrlFromBlob(Blob([data]));
AnchorElement(href: url)
..setAttribute('download', '<downloaded_file_name.pdf>')
..click();
}
);

by following the steps below, you can download the file automatically by the browser and save it in the download directory.
In this method, http and universal_html packages are used.
The important thing is to manage Multiplatform-Mode and using this code, is better you create 3 separate dart files.
switch_native_web.dart
web.dart
native.dart
/// switch_native_web.dart
import 'native.dart' if (dart.library.html) 'web.dart' as switch_value;
class SwitchNativeWeb {
static void downloadFile({required String url,
required String fileName ,required String dataType}){
switch_value.downloadFile(dataType: dataType,fileName: fileName,url: url);}
}
...
/// web.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:universal_html/html.dart' as universal_html;
Future<void> downloadFile(
{required String url,
required String fileName,
required String dataType}) async {
try {
// first we make a request to the url like you did
// in the android and ios version
final http.Response r = await http.get(
Uri.parse(url),
);
// we get the bytes from the body
final data = r.bodyBytes;
// and encode them to base64
final base64data = base64Encode(data);
// then we create and AnchorElement with the html package
final a =
universal_html.AnchorElement(href: '$dataType;base64,$base64data');
// set the name of the file we want the image to get
// downloaded to
a.download = fileName;
// and we click the AnchorElement which downloads the image
a.click();
// finally we remove the AnchorElement
a.remove();
} catch (e) {
print(e);
}
}
...
/// native.dart
Future<void> downloadFile({required String url, required String fileName,
required String dataType}) async {}
And using the following sample code for calling the downloadFile method wherever you need:
...
GestureDetector(
onTap: () => SwitchNativeWeb.downloadFile(
url: "https://... your url ..../download.jpg",
fileName: "download.jpg",
dataType: "data:image/jpeg"),
child: Text('download')
)
...
I only wrote the code related to web download (according to the question), you can write the code related to ios and android download in the native .dart file.

Use Dio Library.
dependencies:
dio: ^3.0.10
to download file
response = await dio.download("https://www.google.com/", "./xx.html");
this video will help you.

Related

How to create a Button that allow user to download a specific file Flutter

I create a flutter app and I have this one CSV file that used as a template for user. I want to provide a Button that allow user to download this CSV file, so they can use it to have CSV file that already have our template.
The problem is I don't know if the best way is to first store the file online and get the url and use it on the flutter downloader URL or keep it in the local code asset and refer to that file when user tap the download template button. Currently I'm applying the second option and it doesn't work (I don't know if this option is possible or not), the download always fail. I'm using flutter_downloader package.
How to fix this ?
Here's my code, Is something wrong with my code ?
/// Check if the file exist or not
if (await File(externalDir!.path + "/" + fileName).exists()) {
OpenFilex.open(externalDir!.path + "/" + fileName);
} else {
/// Download the file if it doesn't exist in the user's device
final String localPath = (await getApplicationDocumentsDirectory()).path;
/// Dummy file name I want use (it exist in my asset dir"
const String fileName = 'add.png';
final data = await rootBundle.load('assets/logo/add.png');
final bytes = data.buffer.asUint8List();
final File file = File('$localPath/$fileName');
await file.writeAsBytes(bytes);
/// Download the file
final taskId = await FlutterDownloader.enqueue(
url: '',
savedDir: localPath,
fileName: fileName,
showNotification: true,
openFileFromNotification: true,
);
}
To load a file from the AppBundle and then save it to the users phone, do the following:
Put the file in assets/filename.csv and declare it in your pubspec like this:
flutter:
assets:
- assets/filename.csv
Load the file in your code:
import 'package:flutter/services.dart' show ByteData, rootBundle;
(...)
var data = (await rootBundle.load('assets/filename.csv)).buffer.asInt8List();
Save the data to a file (you need the path-provider package if you want to copy the exact code):
import 'package:path_provider/path_provider.dart' as pp;
(...)
var path = (await pp.getApplicationDocumentsDirectory()).path;
var file = File('$path/filename.csv');
await file.writeAsBytes(data, flush: true);
Edit: As Stephan correctly pointed out, if you want to store the file in the downloads folder, you will find additional information about that here. Thank you Stephan!

Flutter - cannot download audio files

It's been 3 days that I try to fix an issue with the download of audio files with my Flutter application. When I try to download audio files, the request keep the "pending" status and finish with no error.
I have research a lot and find something about the contentLength of the client who is always at 0 but it doesn't help.
Now I have tried to make a get request to a website with sample audio files and it doesn't work too. I have tested via Postman and it always work.
My function:
Future<void> _download(String url, String filepath) async {
final response = await this.get("https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3");// await this.get("$baseURL$url");
log("Try to get audio files: ${response.isOk}");
if (response.isOk) {
File file = File(filepath);
final raf = file.openSync(mode: FileMode.write);
response.bodyBytes.listen((value) {
raf.writeFromSync(value);
}, onDone: () {
log("closed $filepath");
raf.closeSync();
});
}
}
The response.isOk is always false.
I used GetConnect from GetX package who used httpClient.
Via Dart devtools I obtain this from the request:
https://prnt.sc/1q3w33z
https://prnt.sc/1q3x9ot
So I used another package: Dio and now it works.

Flutter Web: Show PDF or Any File from Assets on another browser tab or window

Recently, I was working on the portfolio website where I need to show the user's CV which was in the PDF format on another tab.
Since this was a standalone Web Project, I didn't want to handle PDF viewing for iOS and Android.
First, you need to install this package: universal_html
flutter pub add universal_html
import the package in your file
import 'package:universal_html/html.dart' as html;
And here is the method:
Future<void> showCV() async {
var bytes = await rootBundle.load("assets/files/cv.pdf"); // location of your asset file
final blob = html.Blob([bytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
}
Voila !
var bytes = await rootBundle.load("assets/files/cv.pdf"); // location of your
asset file
final blob = html.Blob([bytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
Does it work in web hosting also ? because in my case this code is working in local host but not in web host.

Saving images and videos for offline access

I am developing an app that fetches a custom object from my REST API. The object's class is called MyItem and it looks like this:
class MyItem {
String title;
String profilePicURL;
String videoURL;
}
As you can see, the class contains two URLs, that points to a png and mp4 files.
I would like to implement a feature, which allows the user to download the object, in order to access its content offline. I have no problem saving the title property, but how can I save the two URLs (because I don't want the URL itself to be saved, I would like to save the file it points to).
Any idea what is the best way doing that in Flutter and Dart?
Thank you!
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
var directory = await getApplicationDocumentsDirectory();
Dio dio = Dio();
//Below function will download the file you want from url and save it locally
void Download(String title, String downloadurl) async{
try{
await dio.download(downloadurl,"${directory.path}/$title.extensionoffile",
onReceiveProgress: (rec,total){
print("Rec: $rec, Total:$total");
setState(() {
//just to save completion in percentage
String progressString = ((rec/total)*100).toStringAsFixed(0)+"%";
}
);
});
}
catch(e){
//Catch your error here
}
}
Now again wherever you want just use
var directory = await getApplicationDocumentsDirectory();
String filepath = "{directory.path}/filename.fileextension";
Now you can use this Image.file('filepath'); //to display those image
also you can use
video player plugin
where again VideoPlayerController.file('filepath') //to show video but read documention properly
These are just a whole steps or a broader view, you need to use them as a map and build your code.That is have a proper file name and extension saved or correctly fetched or mapped

Looking for a good sample working code for downloading any file from URL in flutter. If its with native downloader then this will be very good

Looking for a good sample working code for downloading any file from URL in flutter. If its with native downloader then this will be very good. Please help me with sample of code to download any file using native downloader in flutter.
I have used few libraries but didn't turned out well.
For a mobile device, I used the http package to download a file to the applications document directory
First, create a httpClient object
static var httpClient = new HttpClient();
Then you can create a function like this to download the file:
Future<void> _downloadFile({
required String fileName,
}) async {
String url = ...;
var request = await httpClient.getUrl(Uri.parse(url));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
String dir = (await getApplicationDocumentsDirectory())!.path;
File file = new File('$dir/$fileName'); // Note: Filename must contain the extension of the file too, like pdf, jpg etc.
await file.writeAsBytes(bytes);
}
For a flutter web application, I felt the url_launcher package was the easiest to work with.
_launchURL() async {
String url = ...;
if (await canLaunch(url)) {
await launch(url);
print('URL Launcher success');
} else {
throw Exception('Could not launch $url');
}
}
The url_launcher package code works even for a mobile device but it opens a new browser window to download the required file which is not a good user experience so I have used 2 approaches for the same problem.
Hope I have answered your query.