after using file.copy(path) and getting the new file i get the previos file at that location - flutter

I'm trying to update a locally saved image file (user's profile picture).
This is how I do it:
Future<void> setProfilePic(File newProfilePic) async {
String profilePicPath = (await getApplicationDocumentsDirectory()).path +
Platform.pathSeparator +
"profilePic.jpg";
await newProfilePic.copy(profilePicPath); }
Then I try to get the profile picture like so:
Future<File> getCurrentUserProfilePic() async {
String filePath =
(await getApplicationDocumentsDirectory()).path + "/profilePic.jpg";
File profilePicFile = File(filePath);
return profilePicFile; }
The profile picture I get is the previous picture located in that file.
Only after I reopen the app, the widget shows the new profile picture.
I do use await when calling the get function and I do setState().
Does anyone know what the problem is?

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!

In file picker in flutter, path was not unique

I'm trying with two different images with same name. But the path was same for two picked images. it was not unique.So that I uploaded in server second image with the same name of first uploaded image. But server had both the image are same and it had first image. So how to handle this case and customize the path?
You can use the path_provider to define the customize directory on your app.
So, copy the file with your customize path and rename the file name.
BTW, do NOT save the absolute path of File on iOS.
The iOS use SandBox to access the file. When you get the file path every time. The file path will be different.
class FileUtils {
final String avatarPath = '/avatar/';
Future<String> getAvatarDirectoryPath() async {
final String appDirPath = await getApplicationSupportDirectory().path;
final Directory avatarDirPath = await Directory(appDirPath + avatarPath).create();
return directory.path;
}
}
// Example
{
final XFile? image = await ImagePicker().pickImage(source: ImageSource.camera);
final File imageFile = File(image.path);
final File newFile = File(await FileUtils().getAvatarDirectoryPath() + 'userAvatar.png');
await imageFile.copy(newFile.path);
}

How to record a video with Camera Plugin in flutter?

I have this page where the camera is initialized and ready with a button that will record and stop the video, so I tried this :
FlatButton(
onPressed: () => {
!isRecording
? {
setState(() {
isRecording = true;
}),
cameraController.prepareForVideoRecording(),
cameraController.startVideoRecording('assets/Videos/test.mp4')
}
: cameraController.stopVideoRecording(),
},
............
but throws this error : nhandled Exception: CameraException(videoRecordingFailed, assets/Videos/test.mp4: open failed: ENOENT (No such file or directory)).
I don't understand, I don't want to open this file I want to save it there, Is there sth wrong with my code ?
In the new version, static method startRecordingVideo doesn't take any string parameter.
When you want to start the recording just see whether a video is already getting recorded, if not start
if (!_controller.value.isRecordingVideo) {
_controller.startVideoRecording();
}
and when you want to finish the recording you can call the static method stopVideoRecording() and it will give you a object of the class XFile, it will have the path to your video.
if (_controller.value.isRecordingVideo) {
XFile videoFile = await _controller.stopVideoRecording();
print(videoFile.path);//and there is more in this XFile object
}
This thing has worked for me. I am new to flutter please improve my answer if you know more.
You are trying to save a video in your assets folder which is not possible ,
What you need to do is to save to device locally either common folders like downloads or app directory.
Here is an example of how to go about it
dependencies:
path_provider:
Flutter plugin for getting commonly used locations on host platform
file systems, such as the temp and app data directories.
We will be saving the video to app directory.
We need to get the path to the directory where the file is or will be. Usually a file is put in the application's document directory, in the application's cache directory, or in the external storage directory. To get the path easily and reduce the chance of type, we can use PathProvider
Future<String> _startVideoRecording() async {
if (!controller.value.isInitialized) {
return null;
}
// Do nothing if a recording is on progress
if (controller.value.isRecordingVideo) {
return null;
}
//get storage path
final Directory appDirectory = await getApplicationDocumentsDirectory();
final String videoDirectory = '${appDirectory.path}/Videos';
await Directory(videoDirectory).create(recursive: true);
final String currentTime = DateTime.now().millisecondsSinceEpoch.toString();
final String filePath = '$videoDirectory/${currentTime}.mp4';
try {
await controller.startVideoRecording(filePath);
videoPath = filePath;
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
//gives you path of where the video was stored
return filePath;
}

How correcty evict image cache?

I'm trying to evict the image cache before take a picture, but it doesn't work and I cannot reupdate an image with the same name because it gives me cache error that the file already exists.
Directory pathCache;
String pathFile;
pathCache = await getTemporaryDirectory();
pathFile = pathCache.path+"/"+profilo+'.jpg';
print(pathFile);
try {
bool res =imageCache.evict(pathFile);
print("eviction result : $res");
imageCache.clear();
}
catch(e) {
print(e.toString());
}
try {
// Ensure that the camera is initialized.
await _initializeControllerFuture;
// Construct the path where the image should be saved using the
// pattern package.
final path = join(
// Store the picture in the temp directory.
// Find the temp directory using the `path_provider` plugin.
(await getTemporaryDirectory()).path,
profilo+'.jpg',
);
// Attempt to take a picture and log where it's been saved.
await _controller.takePicture(path);
What I'm missing?
Thanks
You are trying to clear only the cache, but the file still exists. You need to do:
Remove the old file (from the temporary directory)
Clear the cache
Take the new picture
File pictureFile = File(path);
if (pictureFile.existsSync()) {
pictureFile.deleteSync();
imageCache.clear();
}
...
await _controller.takePicture(path);

Flutter: Custom name for screenshot image

I am following the following flutter package to take a screenshot of my one app page:
https://pub.dev/packages/screenshot
I have successfully implemented the example and I can see my screenshots in the gallery.
My issue is that I would like to be able to NAME those images when they are stored in the gallery using some sort of numbering system. e.g. INV_0001, INV_0002.
Is there a way to do this in code? I have the following code that successfully takes the screenshot, but does not rename the file.
CODE
_imageGallerySaver() async {
final directory = (await getApplicationDocumentsDirectory()).path; //from path_provide package
String fileName = "Bob";
String pathName = '$directory/$fileName.png';
//print(path);
screenshotController
.capture(
path: pathName,
).then((File image) async {
print("image: $image");
setState(() {
_imageFile = image;
});
print(pathName);
final result =
await ImageGallerySaver.saveImage(image.readAsBytesSync());
print("File Saved to Gallery. result: $result");
//print("path: $path");
}).catchError((onError) {
print(onError);
});
}
SNIPPET
print("File Saved to Gallery. result: $result");
results in the following output:
File Saved to Gallery. result: file:///storage/emulated/0/app_name/1581602261670.png
I would like to rename the "1581602261670" part, if possible. Thank you
In your code, you are passing that file name to construct the path, then why not change the name there itself.
Anyway, you can rename an existing file using
await file.rename (newPath
):
Can't rename files using this method. Need to use a package called Gallery Saver:
https://pub.dev/packages/gallery_saver
This package allows you to set your own file name and save to the gallery.