File modified data is always current time - flutter

I am using the following code snippet to attempt to retrieve the modified time of a file:
import 'dart:io';
import 'package:image_picker/image_picker.dart';
final picker = ImagePicker();
final pickedFile = await picker.getVideo(source: ImageSource.gallery);
final file = File(pickedFile.path);
print("file modified time: ${file.lastModifiedSync().toIso8601String()}");
Whenever I run the the above snippet, regardless of the file, it prints the current dateTime as opposed to the file's modified dataTime

The way the image_picker work is it creates a temporary copy of the file which you are about to upload in your app. With this implementation, the "current date" you are mentioning is the logically the file's "last modified date" (or creation date). So for now, you may not be able to retrieve it using this plugin.
However, with Flutter's Platform Channels, you should be able to retrieve the file's attributes, eg. for Android, using BasicFileAttributes in native code.
For example in Android:
File file = ...;
BasicFileAttributes attr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
long lastModifiedAt = attr.lastModifiedTime();
Then using platform channels, you can pass the data like this to Flutter:
result.success(lastModifiedAt)
References
BasicFileAttributes
https://stackoverflow.com/a/48431255/10942908
Flutter's Platform Channels

I don't believe this information is available, unfortunately (at least on Android, not sure about iOS)

Tested using the file_picker package, hope that can help up with the image_picker.
You can use the cross_file package.
FilePickerResult? result = await FilePicker.platform.pickFiles();
final resultFile = result.files.first;
final resultFilePath = resultFile.path;
if (resultFilePath == null) {
throw EntityPathException();
}
/// Class from cross_file package
final xfile = XFile(resultFilePath);
final lastModified = await xfile.lastModified();

You can use multi_image_picker package instead. The creation time of the selected image(s) can be accessed through the MetaData class as indicated below:
List<Asset> images = await MultiImagePicker.pickImages(maxImages: 10, enableCamera: true);
Metadata metadata = await images[0].metadata;
DateTime takenOn = metadata.exif.dateTimeOriginal;

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 image picker reduce file size with provider and flutter_image_compress

I am using image picker to pick image from device(App) and after that stored that file in provider class like that.
File? _img;
get img=> _img;
void putbannerimg(File img) {
_img = img;
notifyListeners();
}
I found out that image picker does not compress png images, I tried compressing it with flutter_image_compress
compressFile() async {
final formservice = Provider.of<PostForm>(context, listen: false);
File file = formservice.bannerfile;
final result = await FlutterImageCompress.compressWithFile(
file.absolute.path,
quality: 54,
);
formservice.putbannerimg(File.fromRawPath(result!));
}
I tried this way And other multiple ways but getting different different errors I want to upload this file in firebase storage like this
var task = storageicon.putFile(formservice.iconfile);
please tell me where I am going wrong, without compress file all things are working fine
Edit: I found out that path should be a string how can I parse local code file in that
If you are using the "flutter_image_compress" package
You may have to use the compress function for files stored on the phone like this:
Future<File> testCompressAndGetFile(File file, String targetPath) async {
var result = await FlutterImageCompress.compressAndGetFile(
file.absolute.path, targetPath,
quality: 88,
rotate: 180,
);
print(file.lengthSync());
print(result.lengthSync());
return result;
}
"compressAndGetFile()" returns a file while "compressWithFile()" returns a Uint8List.
If i understand your last question right, you want to use an image built into your application by default.
For this, you have to open your "pubsepc.yaml", go to the "flutter:" mark and add "assets:" like so:
flutter:
assets:
- path
"path", in my example, describes a top level folder containing assets like pictures.
You can freely describe its name.

Get file path from system directory using Flutter web (chrome) to read file content Eg: CSV or Text file

Package tried: https://pub.dev/packages/file_picker
Tried the example code implementation shared via GitHub. But the file path is returned as null for
web platform. Where same implementation in mobile platform return the path as expected.
https://github.com/miguelpruivo/flutter_file_picker/blob/master/example/lib/src/file_picker_demo.dart
Things aware of:
Path_Provider - Not supported for web
dart-io-library - Not supported for web
Open issue in Flutter Repo
Goal is to read the file from the path and not to upload. Any workaround to achieve this will be helpful.
Flutter channel: beta
As mentioned in the file_picker FAQ:
Paths aren't inaccessible from browsers since those provide fake paths. If you want to create a File instance to upload it somewhere, like FireStorage, you can do so with the bytes directly.
final result = await FilePicker.platform.pickFiles(type: FileType.any, allowMultiple: false);
if (result.files.first != null){
var fileBytes = result.files.first.bytes;
var fileName = result.files.first.name;
print(String.fromCharCodes(fileBytes));
}
I have a function for picking image from computer. Might work for you.
import 'dart:html';
void uploadImage({#required Function(File file) onSelected}) {
InputElement uploadInput = FileUploadInputElement()..accept = 'image/*';
uploadInput.click();
uploadInput.onChange.listen((event) {
final file = uploadInput.files.first;
final reader = FileReader();
reader.readAsDataUrl(file);
reader.onLoadEnd.listen((event) {
onSelected(file);
});
});
}

Store image uploaded by user into Flutter Web as an actual .jpg file

I am using the flutter_web_image_picker package to allow the user to select -and then upload to Firebase- an image.
However, the package returns an image widget, which I can display, but I cannot upload to Firebase. Therefore, I am trying to read the package's code and update it to fit my needs.
In general, I think the packages main functionalities are:
It gets the file
//...
final reader = html.FileReader();
reader.readAsDataUrl(input.files[0]);
await reader.onLoad.first;
final encoded = reader.result as String;
Then it 'strippes' it
final stripped = encoded.replaceFirst(RegExp(r'data:image/[^;]+;base64,'), '');
final imageName = input.files?.first?.name;
//...
To finally return it as a Widget:
final imageName = imageName;
final imageData = base64.decode(stripped);
return Image.memory(imageData, semanticLabel: imageName);
As I said, it works perfectly, however, I need to adapt it to my needs:
I would like to get the image as a .jpg file so that I can upload it to Firebase.
Is any of the variables above the actual .jpg file? Is there any transformation that I should perform to get a .jpg file?
Thanks!
I based my answer on this post.
Basically, on the flutter_web_image_picker package, before the code I posted, there were a few lines that get an actual html file:
final html.FileUploadInputElement input = html.FileUploadInputElement();
input..accept = 'image/*';
input.click();
await input.onChange.first;
if (input.files.isEmpty) return null;
Then using firebase's pacakge, I uploaded the image as follow:
import 'package:firebase/firebase.dart' as fb;
fb.StorageReference storageRef = fb.storage().ref('myLocation/filename.jpg');
fb.UploadTaskSnapshot uploadTaskSnapshot = await storageRef.put(input.files[0]).future;
Uri imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
return imageUri;

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