I am writing an app that uploads an image to a server, and instead of just showing a spinner, I\'d love to be able to get progress on the status of that upload.
Ad
Screenshot:
This solution
import 'package:http/http.dart' as http;
int _total = 0, _received = 0;
http.StreamedResponse _response;
File _image;
List<int> _bytes = [];
Future<void> _downloadImage() async {
_response = await http.Client().send(http.Request('GET', Uri.parse("https://upload.wikimedia.org/wikipedia/commons/f/ff/Pizigani_1367_Chart_10MB.jpg")));
_total = _response.contentLength;
_response.stream.listen((value) {
setState(() {
_bytes.addAll(value);
_received += value.length;
});
}).onDone(() async {
final file = File("${(await getApplicationDocumentsDirectory()).path}/image.png");
await file.writeAsBytes(_bytes);
setState(() {
_image = file;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton.extended(
label: Text("${_received ~/ 1024}/${_total ~/ 1024} KB"),
icon: Icon(Icons.file_download),
onPressed: _downloadImage,
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Center(
child: SizedBox.fromSize(
size: Size(400, 300),
child: _image == null ? Placeholder() : Image.file(_image, fit: BoxFit.fill),
),
),
),
);
}
Try dio library. The onSendProgress callback would be helpful.
example:
response = await dio.post(
"http://www.example.com",
data: data,
onSendProgress: (int sent, int total) {
print("$sent $total");
},
);
Reference: https://github.com/flutterchina/dio/issues/103
The way that you are already using Stream means that you are not reading the whole file into memory. It's being read in as, probably, 64k chunks.
You could intercept the stream between the producer (File) and consumer (HttpClient) with a StreamTransformer, like this:
int byteCount = 0;
Stream<List<int>> stream2 = stream.transform(
new StreamTransformer.fromHandlers(
handleData: (data, sink) {
byteCount += data.length;
print(byteCount);
sink.add(data);
},
handleError: (error, stack, sink) {},
handleDone: (sink) {
sink.close();
},
),
);
....
await request.addStream(stream2);
You should see byteCount incrementing in 64k chunks.