Previously, like all developers we use a HttpUrlConnection or similar Client for creating a connection and uploading a file to the server. If you are using Volley or any other Http client library. Then I am sure they don’t let you reinvent the wheel.
In this post, we are going to upload a bitmap (usually an image bitmap which can be obtained from the camera or from storage)
Here are the steps:
- We compress the Bitmap to the standard image format along with the compression.
- We create a ByteArray of newly created Bitmap’s ByteArrayOutpuStream.
- We create a new data stream and add single or multiple files as per the Multipart standard.
- When the DataOutputStream is created which hold the compressed bitmap and it’s ready to pass using MultiPartRequest
/* MutipartRequest class */
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
public class MultipartRequest extends Request<NetworkResponse> { private final Response.Listener<NetworkResponse> mListener; private final Response.ErrorListener mErrorListener; private final Map<String, String> mHeaders; private final String mMimeType; private final byte[] mMultipartBody; public MultipartRequest(String url, Map<String, String> headers, String mimeType, byte[] multipartBody, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) { super(Method.POST, url, errorListener); this.mListener = listener; this.mErrorListener = errorListener; this.mHeaders = headers; this.mMimeType = mimeType; this.mMultipartBody = multipartBody; } @Override public Map<String, String> getHeaders() throws AuthFailureError { return (mHeaders != null) ? mHeaders : super.getHeaders(); } @Override public String getBodyContentType() { return mMimeType; } @Override public byte[] getBody() throws AuthFailureError { return mMultipartBody; } @Override protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) { try { return Response.success( response, HttpHeaderParser.parseCacheHeaders(response)); } catch (Exception e) { return Response.error(new ParseError(e)); } } @Override protected void deliverResponse(NetworkResponse response) { mListener.onResponse(response); } @Override public void deliverError(VolleyError error) { mErrorListener.onErrorResponse(error); } } |
/* Compressing bitmap and creating Multipart Request*/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
private void uploadImage(Bitmap thumbnailBitmap) { try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); if (thumbnailBitmap != null) { thumbnailBitmap.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream); } byte[] fileByteArray = byteArrayOutputStream.toByteArray(); ByteArrayOutputStream byteArrayOutputStream2 = new ByteArrayOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream2); try { // the first file buildPart(dataOutputStream, fileByteArray, "picture.jpg"); // send multipart form data necesssary after file data dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); // pass to multipart body multipartBody = byteArrayOutputStream2.toByteArray(); } catch (IOException e) { e.printStackTrace(); } String url = ApplicationConstant.HOME_URL + UPLOAD_PROFILE_PIC_CONTROLLER ; MultipartRequest multipartRequest = new MultipartRequest(url, null, mimeType, multipartBody, new Response.Listener<NetworkResponse>() { @Override public void onResponse(NetworkResponse response) { Toast.makeText(mContext, getString(R.string.refreshing_profile_image), Toast.LENGTH_SHORT).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { try { Toast.makeText(mContext.getApplicationContext(), getString(R.string.error_please_try_again), Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } } }); VolleySingleton.getInstance(mContext).addToRequestQueue(multipartRequest); } catch (Exception e) { e.printStackTrace(); } } |
/* build different part in the data output stream */
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
private void buildPart(DataOutputStream dataOutputStream, byte[] fileData, String fileName) throws IOException { dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd); dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"" + lineEnd); dataOutputStream.writeBytes(lineEnd); ByteArrayInputStream fileInputStream = new ByteArrayInputStream(fileData); int bytesAvailable = fileInputStream.available(); int maxBufferSize = 1024 * 1024; int bufferSize = Math.min(bytesAvailable, maxBufferSize); byte[] buffer = new byte[bufferSize]; // read file and write it into form... int bytesRead = fileInputStream.read(buffer, 0, bufferSize); while (bytesRead > 0) { dataOutputStream.write(buffer, 0, bufferSize); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = fileInputStream.read(buffer, 0, bufferSize); } dataOutputStream.writeBytes(lineEnd); } |
Hope from now you don’t need AsyncTask and HttpUrlConnection classes when you are using some Http client library.
Stay updated !!