2

There are several questions discussing ways in which progress indication can be added to HTTP file uploads in Android using the multipart/form-data data format. The typical approach suggested is epitomized by the top answer in Can't grab progress on http POST file upload (Android) -- include the MultipartEntity class from the full Apache HTTPClient library, and then wrap the input stream it uses to get data in one that counts bytes as they're read.

This approach works for this case, but unfortunately does not work for requests sending data via UrlEncodedFormEntity, which expects its data to be passed to it in Strings rather than InputStreams.

So my question is, what approaches are available to determine progress for uploads via this mechanism?

Community
  • 1
  • 1
Jules
  • 14,841
  • 9
  • 83
  • 130

1 Answers1

6

You can override the #writeTo method of any HttpEntity implementation and count bytes as they get written to the output stream.

DefaultHttpClient httpclient = new DefaultHttpClient();
try {
   HttpPost httppost = new HttpPost("http://www.google.com/sorry");

   MultipartEntity outentity = new MultipartEntity() {

    @Override
    public void writeTo(final OutputStream outstream) throws IOException {
        super.writeTo(new CoutingOutputStream(outstream));
    }

   };
   outentity.addPart("stuff", new StringBody("Stuff"));
   httppost.setEntity(outentity);

   HttpResponse rsp = httpclient.execute(httppost);
   HttpEntity inentity = rsp.getEntity();
   EntityUtils.consume(inentity);
} finally {
    httpclient.getConnectionManager().shutdown();
}

static class CoutingOutputStream extends FilterOutputStream {

    CoutingOutputStream(final OutputStream out) {
        super(out);
    }

    @Override
    public void write(int b) throws IOException {
        out.write(b);
        System.out.println("Written 1 byte");
    }

    @Override
    public void write(byte[] b) throws IOException {
        out.write(b);
        System.out.println("Written " + b.length + " bytes");
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        out.write(b, off, len);
        System.out.println("Written " + len + " bytes");
    }

}
ok2c
  • 26,450
  • 5
  • 63
  • 71