MultipartEntityBuilder with progressbar

时光毁灭记忆、已成空白 提交于 2019-12-04 21:19:48
Peter O.

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. 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;
        }
    }
    

    }

  2. 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.

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

    }

  3. Call upload within a Acitvity:

    private void _upload() {

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

    }

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!