t not that easy? Because if you are developing for mobile, the action code to do this will be one thing. If you are developing for the Web it will be another. The web uses DOM, quite a different system, to manage downloads, something you do not need to know, but it's the reason. Downloads are done differently. But to make matters worse, if you want to have an action that downloads from the web, the dependency dart:html' as html is the way to go, but it will crash on compile when you compile to mobile. If you publish to the web, no issues.
So here are several actions you can use, and how to get around the above issue. First, you may need two actions one for the web and another for mobile. Here they are. BTW, this is just a preference, an action that does not compile in FF will eventually fail. Yes, you can exclude them in FF, but they will bite you in the backside later. All these actions compile in FF. First the one for mobile.
// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'dart:io';
import 'package:dio/dio.dart';
// import 'package:path_provider/path_provider.dart';
import 'package:document_file_save_plus/document_file_save_plus.dart';
import 'package:mime_type/mime_type.dart';
Future downloadAnyFile(String? url) async {
// Add your function code here!
String? ext = (url!.split(".").last);
String? extension = (ext.split("?").first);
Dio dio = Dio();
try {
// Fetch the file
Response response =
await dio.get(url, options: Options(responseType: ResponseType.bytes));
// Get the download directory path
// Directory appDocDir = await getApplicationDocumentsDirectory();
// String appDocPath = appDocDir.path;
// Generate a unique file name
String fileName =
'downloaded_file_${DateTime.now().millisecondsSinceEpoch.toString()}.$extension';
String? mimeType = mime(fileName);
DocumentFileSavePlus().saveFile(response.data, fileName, mimeType!);
// saveFile(response.data, fileName, mimeType);
// Create the file path
// String filePath = '$appDocPath/$fileName';
// Write the file
//File file = File(filePath);
//await file.writeAsBytes(response.data, flush: true);
// print('File downloaded to: $filePath');
} catch (e) {
print('Error downloading file: $e');
}
}
And now the one for the web
// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'package:dio/dio.dart';
import 'package:mime_type/mime_type.dart';
//import 'dart:html' as html;
Future downloadAnyWebFile(String? url) async {
/*
Dio dio = Dio();
try {
// Fetch the file
Response response =
await dio.get(url!, options: Options(responseType: ResponseType.bytes));
// Generate a unique file name
String? ext = (url!.split(".").last);
String? extension = (ext.split("?").first);
String fileName =
'downloaded_file_${DateTime.now().millisecondsSinceEpoch.toString()}.$extension';
// Create a download link
final anchor = html.AnchorElement(
href: html.Url.createObjectUrlFromBlob(html.Blob([response.data])));
anchor.download = fileName;
anchor.style.display = 'none';
// Append the link to the body
html.document.body!.children.add(anchor);
// Trigger a click on the link
anchor.click();
// Remove the link from the body
html.document.body!.children.remove(anchor);
print('File downloaded');
} catch (e) {
print('Error downloading file: $e');
}
*/
}
Now you may notice that in the web version I // or /* most of the code out. This is because if you are going to compile for mobile, this code will not build. So the technique is to un /* the code, publish to the web, the re /* the code, let it compile in actions run again, and then create the apk.
According to many sources, there is not way around this, there is no command to compile the web action only for web publication.
DM me or ask questions here. Either way.
So to be clear, there are three download methods we might need.
1, On a mobile app, to the Gallery/Photos, clearly can only work if the file is an image. Solved by ZW in a previous post that inspired this one.
2. Download on a mobile app to the Downloads directory. Can be any file type.
3. Download on the web, can also be any file type.