IMO, you can refer to the following:
Firstly, variables needed:
public class MainActivity extends AppCompatActivity {
private Context mContext = this;
private Uri mFileUri;
private String mFilePath;
private ImageView mImagePreview;
private ProgressBar mProgressBar;
StringRequest mStringRequest;
private long mFileLength;
private MultipartProgressListener multipartProgressListener;
...
Let's assume you got the code to select the image file from phone's camera (gallery) folder and successfully got the file path (mFilePath
).
private void cancelUpload(){
mStringRequest.cancel();
}
private void uploadFile(){
mProgressBar.setProgress(0);
String url = "http://yourserver/fileupload";
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
if (mFilePath != null) {
File file = new File(mFilePath);
if (file.exists()) {
mFileLength = file.length();
FileBody fileBody = new FileBody(file);
entityBuilder.addPart("file", fileBody);
final HttpEntity httpEntity = entityBuilder.build();
mStringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
mFilePath = "";
Log.i("Multipart", response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Multipart", error.toString());
}
}) {
@Override
public String getBodyContentType() {
return httpEntity.getContentType().getValue();
}
@Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
//httpEntity.writeTo(bos);
httpEntity.writeTo(new CountingOutputStream(bos, mFileLength,
multipartProgressListener));
} catch (IOException e) {
Log.e("Multipart", e.toString());
}
return bos.toByteArray();
}
};
mStringRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 5, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
VolleySingleton.getInstance(mContext).addToRequestQueue(mStringRequest);
}
}
}
The following code came from the link in your question, I have made some updates (please note they are no static
anymore)
public interface MultipartProgressListener {
void transferred(long transfered, int progress);
}
public class CountingOutputStream extends FilterOutputStream {
private final MultipartProgressListener progListener;
private long transferred;
private long fileLength;
public CountingOutputStream(final OutputStream out, long fileLength,
final MultipartProgressListener listener) {
super(out);
this.fileLength = fileLength;
this.progListener = listener;
this.transferred = 0;
}
public void write(byte[] b, int off, int len) throws IOException {
Log.i("isCanceled", String.valueOf(mStringRequest.isCanceled()));
if (!mStringRequest.isCanceled()) {
out.write(b, off, len);
if (progListener != null) {
this.transferred += len;
int prog = (int) (transferred * 100 / fileLength);
this.progListener.transferred(this.transferred, prog);
}
} else {
Log.w("Multipart", "Request canceled!");
out.flush();
out.close();
}
}
public void write(int b) throws IOException {
if (!mStringRequest.isCanceled()) {
out.write(b);
if (progListener != null) {
this.transferred++;
int prog = (int) (transferred * 100 / fileLength);
this.progListener.transferred(this.transferred, prog);
}
} else {
Log.w("Multipart", "Request canceled!");
out.flush();
out.close();
}
}
}
P/S: you should select large-file sizes :)