We have to extend Request class of Volley library to upload files to server.
The steps to include this class is as follows:
Make changes to build.gradle file (Application level)
Add the following codes inside android{.....} area:
useLibrary 'org.apache.http.legacy'
As I have used DefaultHttpClient to make a multipart request so to use HTTP library (legacy), the above line of code is required.
also add the below lines inside the same block:
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/ASL2.0'
}
Now, add 2 dependencies inside the dependencies{....} block:
compile('org.apache.httpcomponents:httpmime:4.3.6') {
exclude module: 'httpclient'
}
compile 'org.apache.httpcomponents:httpclient-android:4.3.5'
After you've added the above line, you are ready to make the request class.
Make a custom Request class by extending it
Add the following lines of code to make a custom request class to upload files as a multipart request:
public class MultipartRequest extends Request<String> {
MultipartEntityBuilder entity = MultipartEntityBuilder.create();
HttpEntity httpentity;
private final Response.Listener<String> mListener;
private final HashMap<String, File> mFileParts;
private final Map<String, String> mStringPart;
private final Map<String, String> header;
public MultipartRequest(String url, Response.ErrorListener errorListener,
Response.Listener<String> listener, HashMap<String, File> files,
Map<String, String> mStringPart, Map<String, String> header) {
super(Method.POST, url, errorListener);
this.mListener = listener;
this.mFileParts = files;
this.mStringPart = mStringPart;
this.header = header;
entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
try {
entity.setCharset(CharsetUtils.get("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
buildMultipartEntity();
httpentity = entity.build();
}
private void buildMultipartEntity() {
if (mFileParts != null) {
for (Map.Entry<String, File> entry : mFileParts.entrySet()) {
entity.addPart(entry.getKey(), new FileBody(entry.getValue(), ContentType.create("image/*"), entry.getValue().getName()));
}
}
//entity.addPart(FILE_PART_NAME, new FileBody(mFilePart, ContentType.create("image/jpeg"), mFilePart.getName()));
if (mStringPart != null) {
for (Map.Entry<String, String> entry : mStringPart.entrySet()) {
entity.addTextBody(entry.getKey(), entry.getValue());
}
}
}
@Override
public String getBodyContentType() {
return httpentity.getContentType().getValue();
}
@Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
httpentity.writeTo(bos);
} catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
try {
System.out.println("Network Response " + new String(response.data, "UTF-8"));
return Response.success(new String(response.data, "UTF-8"),
getCacheEntry());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return Response.success(new String(response.data), getCacheEntry());
}
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
if (header == null) {
return super.getHeaders();
} else {
return header;
}
}
@Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}
}
You can now upload the files easily using this class.
An example of creating a multipart request:
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
// Add request params excluding files below
HashMap<String, String> params = new HashMap<>();
params.put("param1", "some_value");
params.put("param2", "some_value");
//Add files to a request
HashMap<String, File> fileParams = new HashMap<>();
fileParams.put("file1", file1);
fileParams.put("file2", file2);
// Add header to a request, if any
Map<String, String> header = new HashMap<>();
header.put("header_key","header_value");
/**
* Create a new Multipart request for sending data in form of Map<String,String > ,along with files
*/
MultipartRequest mMultipartRequest = new MultipartRequest(ServerUrlManager.getServerUrl(ServerUrlManager.UPDATE_PROFILE),
new Response.ErrorListener() {
@Override
public void onErrorResponse(final VolleyError error) {
// error handling
mProgressDialog.cancel();
}
},
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
mProgressDialog.cancel();
//Toast.makeText(getActivity(), "Multipart response check", Toast.LENGTH_SHORT).show();
AppUtil.showLog(response);
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getString(Keys.STATUS).equals(Keys.SUCCESS)) {
Toast.makeText(getActivity(), "Profile updated.", Toast.LENGTH_SHORT).show();
ProfileBean profileBean = ProfileBean.getInstance();
profileBean.setUser_name(etName.getText().toString());
profileBean.setPhone_number(etPhoneNo.getText().toString());
profileBean.setBirthday(etBirthday.getText().toString());
profileBean.setAddress(etAddress.getText().toString());
} else {
Toast.makeText(getActivity(), R.string.err_server_response, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, fileParams, params, header
);
mMultipartRequest.setRetryPolicy(new DefaultRetryPolicy(30000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
/**
* adding request to queue
*/
requestQueue.add(mMultipartRequest);
Hope it helps :)
2 Comment(s)