带有progressbar的MultipartEntityBuilder

时间:2014-04-07 18:44:54

标签: android multipartentity

我使用以下代码通过MultipartEntityBuilder将照片上传到我的服务器。在最后的某个地方它说// FIXME Put your progress bar stuff here!。我不知道是不是应该把整个函数放到Asynctask中,或者在文件上传时我应该怎么做才能显示进度。

我查了Upload a file through an HTTP form, via MultipartEntityBuilder, with a progress bar,但它并没有真正帮助。

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

   } 

这是我的所作所为,但我仍需要你们完成它:

 @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();
            }

        }

1 个答案:

答案 0 :(得分:3)

我试图实现类似的功能(我使用ProgressDialog代替ProgressBar)。您必须使用AsyncTask,因此主线程不会等待您的上传完成(上传必须是异步的)。

  1. HttpEntityWrapped创建扩展程序(信用: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;
        }
    }
    

    }

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

    私有类UploadAsyncTask扩展了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]);
    }
    

    }

  3. Acitvity

    中调用上传

    private void _upload(){

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

    }