有几个问题讨论了如何使用multipart/form数据格式将进度指示添加到android中的http文件上传中。建议的典型方法由Can't grab progress on http POST file upload (Android)中的顶级答案概括——包括完整apache httpclient库中的multipartentity类,然后将它用于获取数据的输入流包装成一个在读取数据时计算字节数的输入流。
这种方法适用于这种情况,但不幸的是,它不适用于通过urlencodedformentity发送数据的请求,urlencodedformentity希望将其数据以字符串而不是inputstreams的形式传递给它。
所以我的问题是,有什么方法可以通过这个机制来确定上传的进度?

最佳答案

您可以重写任何#writeTo实现的HttpEntity方法,并在它们写入输出流时计算字节数。

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");
    }

}

10-05 23:58