14

I am uploading files via org.apache.http.client.HttpClient in android and I need implement progress bar. Is it possible to grab progress from: ?

HttpPost httppost = new HttpPost("some path");
HttpClient httpclient = new DefaultHttpClient();
try {
File file = new File("file path");
InputStream in = new BufferedInputStream(new FileInputStream(file));
byte[] bArray = new byte[(int) file.length()];
in.read(bArray);
String entity = Base64.encodeToString(bArray, Base64.DEFAULT);
httppost.setEntity(new StringEntity(entity));
HttpResponse response = httpclient.execute(httppost);
}

If not, please show an alternative way. Thanks

1

2 Answers 2

22

What you're going to want to do is create an AsyncTask that can handle this for you, overriding the onProgressUpdate method.

Here's a stripped down version of a something I tested in another app using HttpURLConnection. There may be some small redundancies and I think HttpURLConnection may be generally frowned upon, but this should work. Just use this class in whatever Activity class you're using (in this example, I refer to it as TheActivity) by calling new FileUploadTask().execute(). Of course you may need to tweak this to fit the needs of your app.

private class FileUploadTask extends AsyncTask<Object, Integer, Void> {

    private ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        dialog = new ProgressDialog(TheActivity.this);
        dialog.setMessage("Uploading...");
        dialog.setIndeterminate(false);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setProgress(0);
        dialog.show();
    }

    @Override
    protected Void doInBackground(Object... arg0) {
        try {
            File file = new File("file path");
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] bytes = new byte[(int) file.length()];
            fileInputStream.read(bytes);
            fileInputStream.close();

            URL url = new URL("some path");
            HttpURLConnection connection = 
                    (HttpURLConnection) url.openConnection();
            OutputStream outputStream = connection.getOutputStream();

            int bufferLength = 1024;
            for (int i = 0; i < bytes.length; i += bufferLength) {
                int progress = (int)((i / (float) bytes.length) * 100);
                publishProgress(progress);
                if (bytes.length - i >= bufferLength) {
                    outputStream.write(bytes, i, bufferLength);
                } else {
                    outputStream.write(bytes, i, bytes.length - i);
                }
            }
            publishProgress(100);

            outputStream.close();
            outputStream.flush();

            InputStream inputStream = connection.getInputStream();
            // read the response
            inputStream.close();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        dialog.setProgress(progress[0]);
    }

    @Override
    protected void onPostExecute(Void result) {
        try {
            dialog.dismiss();
        } catch(Exception e) {
        }

    }

}
Sign up to request clarification or add additional context in comments.

3 Comments

This isn't efficient as it progresses smoothly till 100 and then stuck on a 100 % after that dialog get dismiss when actually the file gets transfered. so there something missing in above code ?
The actual upload will be start when you flush the outputStream. so the progress is a fake progress
Using HttpURLConnection.setFixedLengthStreamingMode() uploads contents without buffering (see @Songlin answer).
4

I don't think HttpURLConnection simply does the trick, as @Basbous pointed out, the actual data is bufferred until outputStream.flush() is called. According to android issue 3164, it's now fixed in post-froyo platform (android 2.2, sdk version 8), you need use - java.net.HttpURLConnection.setFixedLengthStreamingMode to work around the buffer behavior.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.