I'm using DIO for downloading images from network in my Flutter Application.
In general his is my code:
await Future.forEach(files, (file) async {
print(1);
entriesController.downloadIndex.value++;
if (file["video"] != null && file["video"].isNotEmpty) {
String videoPath = file["video"];
var appDocDir = await getTemporaryDirectory();
String savePath = appDocDir.path + "/$uniqueID.mp4";
await Dio().download(videoPath, savePath);
await ImageGallerySaver.saveFile(savePath);
}
if (file["video"] == null || file["video"].isEmpty) {
print(2);
String imagePath = file["image"];
print(3);
var appDocDir = await getTemporaryDirectory();
print(4);
String savePath = appDocDir.path + "/$uniqueID.jpg";
print(5);
try {
await Dio().download(imagePath, savePath);
} catch (e) {
print(e);
}
print(6);
await ImageGallerySaver.saveFile(savePath);
}
});
This is a loop which builds the network path to download the image and save them to the mobile gallery.
The problem: After maybe 50 downloaded images I get the following error on await Dio().download(imagePath, savePath); catch line:
flutter: DioError [DioErrorType.DEFAULT]: HandshakeException: Connection terminated during handshake
How can I solve this error? Is this maybe a timeout? By the way: The downloaded images are stored on DigitalOcean.
Related
here i'm wrapping the function with the catch error but still the error exists;
'W/NetworkRequest( 3326): error sending network request POST https://firebasestorage.googleapis.com' but the app didn't crash or something.
final profileImageUrl = await uploadImage(profileImage!, 'Profile Pictures')
.catchError((error) {
print(error);
});
Future<String> uploadImage(XFile image, String savedFolderName) async {
try {
storage_ref.Reference firebaseStorageReference =
storage_ref.FirebaseStorage.instance.ref().child(savedFolderName);
storage_ref.UploadTask uploadImage = firebaseStorageReference
.child('${DateTime.now()}')
.putFile(File(image.path));
storage_ref.TaskSnapshot taskSnapshot =
await uploadImage.whenComplete(() {});
String downloadUrl = await taskSnapshot.ref.getDownloadURL();
return downloadUrl;
} catch (error) {
rethrow;
}
}
so this is the my file picking and file upload code
class Storage with ChangeNotifier {
PlatformFile? pickedFile;
UploadTask? uploadTask;
Future uploadFile() async {
final path = 'files/${pickedFile!.name}.png';
final file = File(pickedFile!.path!);
final ref = FirebaseStorage.instance.ref().child(path);
ref.putFile(file);
try {
final snapshot = await uploadTask!.whenComplete(() {});
final urlDownload = await snapshot.ref.getDownloadURL();
print(urlDownload);
} catch (e) {
print("this is the error $e " );
}
}
void pickFile() async {
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path!);
pickedFile = result.files.first;
} else {
print("no image picked");
}}}
the code works for upload the image but after that i didnt get any download link, the error is "Null check operator used on a null value" i dont know how to fix it, im still new in this topic, help please
i got the answer, need to change the uploadFile method to this
Future uploadFile() async {
final path = 'files/${pickedFile!.name}.png';
final file = File(pickedFile!.path!);
FirebaseStorage storage = FirebaseStorage.instance;
Reference ref = storage.ref().child(path);
UploadTask uploadTask = ref.putFile(file);
uploadTask.then((res) {
res.ref.getDownloadURL();
});
try {
final snapshot = await uploadTask.whenComplete(() {});
final urlDownload = await snapshot.ref.getDownloadURL();
print(urlDownload);
} catch (e) {
print("this is the error $e " );
}
}
I am working on an app that should manage downloaded files.
For now I am able to download a file on both platforms, but I would need to know how can I get the downloaded files from the device.
This is the code used to download a file from Internet.
Future<void> downloadFile() async {
bool downloading = false;
var progressString = "";
final imgUrl = "https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4";
Dio dio = Dio();
try {
var dir = await getApplicationDocumentsDirectory();
print("path ${dir.path}");
await dio.download(imgUrl, "${dir.path}/demo.mp4",
onReceiveProgress: (rec, total) {
print("Rec: $rec , Total: $total");
downloading = true;
progressString = ((rec / total) * 100).toStringAsFixed(0) + "%";
});
} catch (e) {
print(e);
}
downloading = false;
progressString = "Completed";
print("Download completed");
}
The path print output for Android is:
path /data/user/0/red.faro.labelconciergeflutter/app_flutter
The path print output for iOS is:
path /var/mobile/Containers/Data/Application/9CFDC9E3-D9A9-4594-901E-427D44E48EB9/Documents
What I need is to know how can an app user access the downloaded files when the app is closed or there is no internet connection to open the file from the original URL?
For getting files from the device you may use file_picker package.
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path);
} else {
// User canceled the picker
}
You also can use the File class from the dart:io library.
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/counter.txt');
}
If your goal is to access commonly used locations on the device’s file system you can use the path_provider plugin.
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path
I want to upload an image to server
I'm using the Image Picker plugin to pick image
this code work without any exception on samsung tab
but Catch error on xiaomi phone.
the onImageButtonPressed run in all devices.
Future<void> onImageButtonPressed({
BuildContext? context,
}) async {
try {
final XFile? pickedFile =
await picker.pickImage(source: ImageSource.camera);
if (pickedFile != null) {
imageFileList!.add(pickedFile);
logger.i('done , image picked');
File image = File(pickedFile.path);
logger.i(image); // on xiaomi and samsung log the same result "File: '/data/user/0/com.grand.technology.driver/cache/8227d4f4-df70-441d-9677-b95b64b1bf323122241454085685040.jpg'"
await uploadOrderPic(order.id.toString(), image);
}
update();
} catch (e) {
pickImageError = e;
logger.e(e);
update();
}
}
but the exception happen here
uploadOrderPic(String id, File image) async {
uploading.value = true;
var response = await OrderApi()
.uploadOrderPic(orderID: id, image: image)
.then((value) {
logger.i(value.data); //samsung tab log Instance of 'UploadedImage' but xiaomi phone catch error
uploading.value = false;
var uploadedImage = (value.data) as UploadedImage;
imageURLsList.add(uploadedImage.url!);
}).catchError((error) {
Get.snackbar('Failed', 'Uploading Image Failed',
backgroundColor: redColor);
logger.e(error); // type 'Null' is not a subtype of type 'UploadedImage' in type cast
});
try {
} on TimeoutException {
Get.snackbar(
'Connection Error', 'Check Your Internet Connection Please!');
} catch (e) {
logger.e(e);
}
}
this code upload image to server
Future<ApiResponse> uploadOrderPic(
{required String orderID,
required File image}) async {
ApiResponse apiResponse = ApiResponse();
var token = await getToken();
try {
var request = http.MultipartRequest("POST", Uri.parse(uploadPicUrl));
request.files.add(await http.MultipartFile.fromPath('image', image.path));
request.fields['id'] = orderID;
request.headers[HttpHeaders.authorizationHeader] = 'Bearer $token';
var response =
await request.send().then((value) => http.Response.fromStream(value));
apiResponse.data =
UploadedImage.fromJson(jsonDecode(response.body)['data']);
} catch (e) {
logger.e(e);
apiResponse.error = serverError;
}
return apiResponse;
}
I am playing a video in my app from the URL. I need to download that video into internal storage of phone. How can I achieve this. Is there any way. I am new to flutter?
You can download video using the following code ....
static var httpClient = HttpClient();
Future<File> downloadFile(String url1, String filename) async {
var request = await httpClient.getUrl(Uri.parse(url1));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
String dir = (await getApplicationDocumentsDirectory()).path;
File file = new File('$dir/$filename');
await file.writeAsBytes(bytes);
return file;
}
Here is an example that can help you
downloadVideo()
{ var url = "Your url";
var status = await Permission.storage.status;
if (!status.isGranted) {
await Permission.storage.request();
}
var tempPath = await ExtStorage.getExternalStoragePublicDirectory(
ExtStorage.DIRECTORY_DOWNLOADS);
try {
var res = await http.get(
'$url',
headers: <String, String>{
'Authorization': _userDataController.userDataModel.token,//if authorization is not required then remove this line
},
);
filePath = tempPath + '/Video1.mp4';//use you own video format
} catch (e) {
print(e);
}}
you have to use permission_handler: ^8.1.2 & http: ^0.13.3 and path_provider: ^2.0.2