具有进度栏的MultipartEntityBuilder [英] MultipartEntityBuilder with progressbar

查看:148
本文介绍了具有进度栏的MultipartEntityBuilder的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码通过MultipartEntityBuilder将照片上传到我的服务器.最后某处显示// FIXME Put your progress bar stuff here!.我不知道是否应该将整个功能放在Asynctask中,或者在上传文件时应该如何显示进度.

I am using the following code to upload a photo to my server with MultipartEntityBuilder. Somewhere at the end it says // FIXME Put your progress bar stuff here!. I don't know if I should put the whole function into an Asynctask or what I should do to display progress while the file is uploaded.

我检查了上传文件通过HTTP表单,通过MultipartEntityBuilder并带有进度条,但这并没有真正的帮助.

I checked Upload a file through an HTTP form, via MultipartEntityBuilder, with a progress bar but it doesn't really help.

public String postFile(String fileName) throws Exception {

          fileName = "/mnt/sdcard/DCIM/100MEDIA/IMAG0309.jpg";

            HttpClient client = new DefaultHttpClient();
            HttpPost post = new HttpPost("http://www.mywebsite.com/upload_file.php");
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();        
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);  

            final File file = new File(fileName);
            FileBody fb = new FileBody(file);
            builder.addPart("file",fb);

            String userid = session_userid;
            builder.addTextBody("userID", userid);

            final HttpEntity yourEntity = builder.build();

            class ProgressiveEntity implements HttpEntity {
                @Override
                public void consumeContent() throws IOException {
                    yourEntity.consumeContent();                
                }
                @Override
                public InputStream getContent() throws IOException,
                        IllegalStateException {
                    return yourEntity.getContent();
                }
                @Override
                public Header getContentEncoding() {             
                    return yourEntity.getContentEncoding();
                }
                @Override
                public long getContentLength() {
                    return yourEntity.getContentLength();
                }
                @Override
                public Header getContentType() {
                    return yourEntity.getContentType();
                }
                @Override
                public boolean isChunked() {             
                    return yourEntity.isChunked();
                }
                @Override
                public boolean isRepeatable() {
                    return yourEntity.isRepeatable();
                }
                @Override
                public boolean isStreaming() {             
                    return yourEntity.isStreaming();
                } // CONSIDER put a _real_ delegator into here!

                @Override
                public void writeTo(OutputStream outstream) throws IOException {

                    class ProxyOutputStream extends FilterOutputStream {

                        public ProxyOutputStream(OutputStream proxy) {
                            super(proxy);    
                        }
                        public void write(int idx) throws IOException {
                            out.write(idx);
                        }
                        public void write(byte[] bts) throws IOException {
                            out.write(bts);
                        }
                        public void write(byte[] bts, int st, int end) throws IOException {
                            out.write(bts, st, end);
                        }
                        public void flush() throws IOException {
                            out.flush();
                        }
                        public void close() throws IOException {
                            out.close();
                        }
                    }

                    class ProgressiveOutputStream extends ProxyOutputStream {

                         int totalSent;

                        public ProgressiveOutputStream(OutputStream proxy) {
                            super(proxy);
                        }
                        public void write(byte[] bts, int st, int end) throws IOException {

                            // FIXME  Put your progress bar stuff here!

                            out.write(bts, st, end);
                        }
                    }

                    yourEntity.writeTo(new ProgressiveOutputStream(outstream));
                }

            };
            ProgressiveEntity myEntity = new ProgressiveEntity();

            post.setEntity(myEntity);
            HttpResponse response = client.execute(post);        

                return getContent(response);

   } 

这是我所做的,但是我仍然需要你们来完成它:

Here is what I did but I still need you guys for finishing it:

 @Override
            protected String doInBackground(HttpResponse... arg0)
            {
              String fileName = "/mnt/sdcard/DCIM/100MEDIA/IMAG0309.jpg";
                HttpClient client = new DefaultHttpClient();
                HttpPost post = new HttpPost("http://www.mywebsite.com/upload_file.php");
                MultipartEntityBuilder builder = MultipartEntityBuilder.create();        
                builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);  

                final File file = new File(fileName);
                FileBody fb = new FileBody(file);
                builder.addPart("file",fb);

                    String userid = session_userid;
                builder.addTextBody("userID", userid);
                final HttpEntity yourEntity = builder.build();

                class ProgressiveEntity implements HttpEntity {
                    @Override
                    public void consumeContent() throws IOException {
                        yourEntity.consumeContent();                
                    }
                    @Override
                    public InputStream getContent() throws IOException,
                            IllegalStateException {
                        return yourEntity.getContent();
                    }
                    @Override
                    public Header getContentEncoding() {             
                        return yourEntity.getContentEncoding();
                    }
                    @Override
                    public long getContentLength() {
                        return yourEntity.getContentLength();
                    }
                    @Override
                    public Header getContentType() {
                        return yourEntity.getContentType();
                    }
                    @Override
                    public boolean isChunked() {             
                        return yourEntity.isChunked();
                    }
                    @Override
                    public boolean isRepeatable() {
                        return yourEntity.isRepeatable();
                    }
                    @Override
                    public boolean isStreaming() {             
                        return yourEntity.isStreaming();
                    } // CONSIDER put a _real_ delegator into here!

                    @Override
                    public void writeTo(OutputStream outstream) throws IOException {

                        class ProxyOutputStream extends FilterOutputStream {

                            public ProxyOutputStream(OutputStream proxy) {
                                super(proxy);    
                            }
                            public void write(int idx) throws IOException {
                                out.write(idx);
                            }
                            public void write(byte[] bts) throws IOException {
                                out.write(bts);
                            }
                            public void write(byte[] bts, int st, int end) throws IOException {
                                out.write(bts, st, end);
                            }
                            public void flush() throws IOException {
                                out.flush();
                            }
                            public void close() throws IOException {
                                out.close();
                            }
                        }

                        class ProgressiveOutputStream extends ProxyOutputStream {
                            public ProgressiveOutputStream(OutputStream proxy) {
                                super(proxy);
                                int totalSent = 0;
                            }
                            public void write(byte[] bts, int st, int end) throws IOException {

                                // FIXME  Put your progress bar stuff here!
                                 //what's totalSize?
                                publishProgress((int) ((end / (float) totalSize) * 100));
                                out.write(bts, st, end);
                            }
                        }

                        yourEntity.writeTo(new ProgressiveOutputStream(outstream));
                    }

                };
                ProgressiveEntity myEntity = new ProgressiveEntity();

                post.setEntity(myEntity);
                HttpResponse response = client.execute(post);        

                    return getContent(response);
//Here it says I should put this into a try catch but then I get an error on
// the doInBackground line saying it needs to return a string

                }

                protected void onProgressUpdate(Integer... progress) {
                    pd.setProgress((int) (progress[0]));
               }

            @SuppressWarnings("deprecation")
            @Override
             protected void onPostExecute(String file_url) {
                pd.dismiss();
                connection.disconnect();
                Toast.makeText(getApplicationContext(), "Ready.", Toast.LENGTH_LONG).show();
            }

        }

推荐答案

我正在尝试实现类似的目的(我使用ProgressDialog而不是ProgressBar).您必须使用AsyncTask,以便主线程不会等待上传完成(上传必须是异步的).

I was trying to achieve something similar (I use ProgressDialog instead of ProgressBar). You have to use AsyncTask so the main thread won't be waiting for your upload to finish (Upload must be asynchronous).

  1. HttpEntityWrapped创建扩展名(来源:

  1. Create a extension for HttpEntityWrapped (credits: here):

public class MyHttpEntity extends HttpEntityWrapper {

private ProgressListener progressListener;

public MyHttpEntity(final HttpEntity entity, final ProgressListener progressListener) {
    super(entity);
    this.progressListener = progressListener;
}

@Override
public void writeTo(OutputStream outStream) throws IOException {
    this.wrappedEntity.writeTo(outStream instanceof ProgressOutputStream ? outStream :
            new ProgressOutputStream(outStream, this.progressListener,
                    this.getContentLength()));
}

public static interface ProgressListener {
    void transferred(float progress);
}

public static class ProgressOutputStream extends FilterOutputStream {

    private final ProgressListener progressListener;

    private long transferred;

    private long total;

    public ProgressOutputStream(final OutputStream outputStream,
                                final ProgressListener progressListener,
                                long total) {

        super(outputStream);
        this.progressListener = progressListener;
        this.transferred = 0;
        this.total = total;
    }

    @Override
    public void write(byte[] buffer, int offset, int length) throws IOException {

        out.write(buffer, offset, length);
        this.transferred += length;
        this.progressListener.transferred(this._getCurrentProgress());
    }

    @Override
    public void write(byte[] buffer) throws IOException {

        out.write(buffer);
        this.transferred++;
        this.progressListener.transferred(this._getCurrentProgress());
    }

    private float _getCurrentProgress() {
        return ((float) this.transferred / this.total) * 100;
    }
}

}

我创建了在Activity中扩展AsyncTask的私有类.在doInBackground中,使用MultipartEntityBuilder添加文件和所需的任何内容.如果上传成功(代码== 200,这是我的自定义json响应),则会调用onPostExecute.

I've created private class that extends AsyncTask in an Activity. In doInBackground you use MultipartEntityBuilder to add your file and anything you want. If upload is successful (code == 200, it's my custom json response), onPostExecute will be called.

私有类UploadAsyncTask扩展了AsyncTask {

private class UploadAsyncTask extends AsyncTask {

private Context context;
private Exception exception;
private ProgressDialog progressDialog;

private UploadAsyncTask(Context context) {

    this.context = context;
}

@Override
protected Boolean doInBackground(String... params) {

    String uploadUrl = URL + "upload";

    HttpResponse response = null;

    try {
        HttpPost post = new HttpPost(uploadUrl);

        // Entity
        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        // Add your file
        multipartEntityBuilder.addPart("file", new FileBody(new File(params[0])));

        // Progress listener - updates task's progress
        MyHttpEntity.ProgressListener progressListener =
                new MyHttpEntity.ProgressListener() {
                    @Override
                    public void transferred(float progress) {
                        UploadAsyncTask.this.publishProgress((int) progress);
                    }
                };

        // POST
        post.setEntity(new MyHttpEntity(multipartEntityBuilder.build(),
                progressListener));

        // Handle response
        GsonBuilder builder = new GsonBuilder();
        LinkedTreeMap object = builder.create().fromJson(
                EntityUtils.toString(client.execute(post).getEntity()),
                LinkedTreeMap.class);

        if ((double) object.get("code") == 200.0) {
            return true;
        }

    } catch (UnsupportedEncodingException | JsonSyntaxException | ClientProtocolException e) {
        e.printStackTrace();
        Log.e("UPLOAD", e.getMessage());
        this.exception = e;
    } catch (IOException e) {
        e.printStackTrace();
    }

    return false;
}

@Override
protected void onPreExecute() {

    // Init and show dialog
    this.progressDialog = new ProgressDialog(this.context);
    this.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    this.progressDialog.show();
}

@Override
protected void onPostExecute(Boolean result) {

    // Close dialog
    this.progressDialog.dismiss();
    if (result) {
        Toast.makeText(getApplicationContext(),
                R.string.upload_success, Toast.LENGTH_LONG).show();
    } else {
        Toast.makeText(getApplicationContext(),
                R.string.upload_failure, Toast.LENGTH_LONG).show();
    }
}

@Override
protected void onProgressUpdate(Integer... progress) {
    // Update process
    this.progressDialog.setProgress((int) progress[0]);
}

}

Acitvity内的呼叫上传:

private void _upload(){

private void _upload() {

UploadAsyncTask task = new UploadAsyncTask(this);
task.execute();

}

这篇关于具有进度栏的MultipartEntityBuilder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆