How to implement file upload progress bar in android
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
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) {
}
}
}
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.