Flutter: How to get upload / download progress for http requests

后端 未结 3 1190
误落风尘
误落风尘 2020-12-01 10:17

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

相关标签:
3条回答
  • 2020-12-01 10:35

    Screenshot:


    This solution

    1. Downloads an image from server.
    2. Shows downloading progress.
    3. After download, the image is saved to device storage.

    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),
            ),
          ),
        ),
      );
    }
    
    0 讨论(0)
  • 2020-12-01 10:43

    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

    0 讨论(0)
  • 2020-12-01 10:44

    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.

    0 讨论(0)
提交回复
热议问题