Uploading image using Google Volley library - android

I am trying to upload an image using Volley library in android but no data is being send to the server side as the file is created but it does not contain any data.
public class ProfilePicSendReq extends Request<String>
{
private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create();
private final Response.Listener<String> mListener;
private final File mImageFile;
protected Map<String, String> headers;
Context context;
public ProfilePicSendReq(Context cntxt, String url, Listener<String> listener, ErrorListener errorListener, File imageFile)
{
super(Method.POST, url, errorListener);
mListener = listener;
mImageFile = imageFile;
buildMultipartEntity();
context = cntxt;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError
{
headers = super.getHeaders();
if (headers == null
|| headers.equals(Collections.emptyMap()))
{
headers = new HashMap<String, String>();
}
headers.put("Accept", "text/plain");
return headers;
}
private void buildMultipartEntity()
{
mBuilder.addBinaryBody(mImageFile.getName(), mImageFile, ContentType.create("image/jpeg"), "profilePic");
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
}
#Override
public String getBodyContentType()
{
String contentTypeHeader = mBuilder.build().getContentType().getValue();
return contentTypeHeader;
}
#Override
public byte[] getBody() throws AuthFailureError
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
mBuilder.build().writeTo(bos);
} catch (IOException e) {
Log.d("PicUploadMsg : ", "IOException writing to ByteArrayOutputStream bos, building the multipart request.");
}
return bos.toByteArray();
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response)
{
String result = new String(response.data);
return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
}
#Override
protected void deliverResponse(String response)
{
mListener.onResponse(response);
}
}
It is the famous sending Mulipart data using volley i have tried several time but no data appears to leave from the client side.

Related

Need help to upload file using multipart/form data

I'm facing problem to upload a file using multipart form data. I have given the screenshot of ARC with the API and my present code. Can anyone give me the proper way how to upload file using this multipart form data.
public class MultiPortRequest<T> extends Request<T> {
private static final String FILE_PART_NAME = "file";
private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create();
private final Response.Listener<String> mListener;
private final File mImageFile;
protected Map<String, String> headers;
public MultiPortRequest(String url,Response.Listener<String> listener,
ErrorListener errorListener,
File imageFile)
{
super(Method.POST, url, errorListener);
mListener = listener;
mImageFile = imageFile;
buildMultipartEntity();
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null
|| headers.equals(Collections.emptyMap())) {
headers = new HashMap<String, String>();
}
headers.put("Identity", "rHTYsg8vZ/KWTaGOsy0eMNhngJMiZiK60pd9jAUQ+fI=");
return headers;
}
private void buildMultipartEntity()
{
mBuilder.addBinaryBody(FILE_PART_NAME, mImageFile, ContentType.create("multipart/form-data"),
mImageFile.getName());
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
}
#Override
public String getBodyContentType()
{
String contentTypeHeader = mBuilder.build().getContentType().getValue();
return contentTypeHeader;
}
#Override
public byte[] getBody() throws AuthFailureError{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try{
mBuilder.build().writeTo(bos);
}
catch (IOException e)
{
VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request.");
}
return bos.toByteArray();
}
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response){
try {
String result = null;
result = new String( response.data, HttpHeaderParser.parseCharset( response.headers ) );
return ( Response<T> ) Response.success( new JSONObject( result ), HttpHeaderParser.parseCacheHeaders(response) );
} catch ( UnsupportedEncodingException e ) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
protected void deliverResponse(T response){
mListener.onResponse( response.toString());
Log.v("yes", String.valueOf(mListener));
}
}
I think this library will help you, I used it before to upload images to my own sever.
https://github.com/gotev/android-upload-service

Multipart Image Request with JSON params in Single Call using volley Framework

I am sending multipart Post request in Volley along with the JSon params {as required by server } , but at server side null params are received .
In this request, I need to send Requested params in one part fist, and the image file in the next part .
Map<String, String> params = new HashMap<String, String>();
params.put("appkey", Constants.REQUEST_API_KEY);
params.put("LoginID",issueRequest.getUserName());
params.put("device_id", issueRequest.getImei().toString());
params.put("tokenID", AppSharedPreferance.getAppSharedPreferanceInstance(mContext).getToken(Constants.REQUEST_TOKEN, null));
params.put("issueId", String.valueOf(mRequestIssueId));
params.put("serverID", String.valueOf(mServerId));
JSONObject requestObj = new JSONObject();
requestObj.put("ISSUE_DATA_KEY", new JSONObject(params));
I am requesting like :
PhotoMultipartRequest<JSONObject> photoMultipartRequest=null;
photoMultipartRequest=new PhotoMultipartRequest<JSONObject>(url, requestObj.toString(), new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(IssueRequest.TAG, "inside Error");
VolleyLog.d(Constants.REQUEST_ERROR, "Error had occured " + error.getCause());
}
}, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.v(IssueRequest.TAG,"Responce -> Issue Attachments "+response);
String status = null;
int code=-1;
try {
code = (int) response.getInt("error_code");
status = response.getString("response_string");
} catch (JSONException e) {
e.printStackTrace();
}
Log.v(IssueRequest.TAG, "code->" + code + "status->" + status + "Responce ->" + response.toString());
}
},
new File(issue.getAttachmentPath().toString()));
photoMultipartRequest.setRetryPolicy(new RetryPolicyClass());
Log.v(TAG, "Issue data " + photoMultipartRequest.toString());
AppController.getInstance().addToRequestQueue(photoMultipartRequest);
When i am printing the response object, it has null params .
{"response_string":"Invalid request.","error_code":"1","required_params":null}
My VolleyRequest Class :
public class PhotoMultipartRequest<T> extends Request<T> {
private static final String FILE_PART_NAME = "file";
private static final String FILE_JSON_PART_NAME = "parms";
private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create();
private final Response.Listener<T> mListener;
private final File mImageFile;
protected Map<String, String> headers;
protected String params;
protected static final String PROTOCOL_CHARSET = "utf-8";
public PhotoMultipartRequest(String url, ErrorListener errorListener, Listener<T> listener, File imageFile){
super(Method.POST, url, errorListener);
mListener = listener;
mImageFile = imageFile;
buildMultipartEntity();
}
public PhotoMultipartRequest(String url,String params, ErrorListener errorListener, Listener<T> listener, File imageFile){
super(Method.POST, url, errorListener);
mListener = listener;
mImageFile = imageFile;
this.params=params;
try {
buildMultipartEntity1();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null
|| headers.equals(Collections.emptyMap())) {
headers = new HashMap<String, String>();
}
headers.put("Accept", "application/json");
return headers;
}
private void buildMultipartEntity1() throws UnsupportedEncodingException {
mBuilder.addPart(FILE_JSON_PART_NAME, new StringBody(params));
mBuilder.addBinaryBody(FILE_PART_NAME, mImageFile, ContentType.create("image/jpeg"), mImageFile.getName());
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
}
private void buildMultipartEntity(){
mBuilder.addBinaryBody(FILE_PART_NAME, mImageFile, ContentType.create("image/jpeg"), mImageFile.getName());
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
}
#Override
public String getBodyContentType(){
String contentTypeHeader = mBuilder.build().getContentType().getValue();
return contentTypeHeader;
}
#Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
mBuilder.build().writeTo(bos);
} catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request.");
}
return bos.toByteArray();
}
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response)
{
try {
String result = null;
result = new String( response.data, HttpHeaderParser.parseCharset( response.headers ) );
return ( Response<T> ) Response.success( new JSONObject( result ), HttpHeaderParser.parseCacheHeaders(response) );
} catch ( UnsupportedEncodingException e ) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}
}
I cannot find any clue of what went wrong. So, can anyone help me to correct my request class?

how to perform file upload using Volley in android?

I want to upload files(images,documents etc) from my android application to my server.I'm using Volley library for network calls in my application.
I'm using the following code to upload files but it is not performing any operation.(showing volley timeout error finally)
public class MultipartRequest extends Request<String> {
private MultipartEntity entity = new MultipartEntity();
private static final String FILE_PART_NAME = "file";
private final Response.Listener<String> mListener;
private final File mFilePart;
private String mStringPart,accessToken;
public MultipartRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, File file,String accessToken)
{
super(Method.POST, url, errorListener);
mListener = listener;
mFilePart = file;
this.accessToken = accessToken;
buildMultipartEntity();
}
private void buildMultipartEntity()
{
entity.addPart(FILE_PART_NAME, new FileBody(mFilePart));
try
{
entity.addPart("Content-Disposition", new StringBody("form-data"));
entity.addPart("dir_path", new StringBody("IzEzOjE3"));
}
catch (UnsupportedEncodingException e)
{
VolleyLog.e("UnsupportedEncodingException");
}
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null
|| headers.equals(Collections.emptyMap())) {
headers = new HashMap<String, String>();
}
headers.put("Content-Type", "multipart/form-data");
headers.put("_pkta",accessToken);
return headers;
}
#Override
public String getBodyContentType()
{
return entity.getContentType().getValue();
}
#Override
public byte[] getBody() throws AuthFailureError
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try
{
entity.writeTo(bos);
}
catch (IOException e)
{
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response)
{
return Response.success("Uploaded", getCacheEntry());
}
#Override
protected void deliverResponse(String response)
{
mListener.onResponse(response);
}
}
please help me on how to implement file upload in android(either by volley or any other)
Try
public MultiPartRequest(String url, String filePath, Response.Listener<String> listener, Response.ErrorListener errorListener)
{
super(Method.POST, url, errorListener);
entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
file = new File(filePath);
mListener = listener;
buildMultipartEntity();
}
also, in my case I didn't override getHeaders, just passed other values with addPart, e.g:
entity.addPart("file", new FileBody(file, "image/jpeg")); // for image
entity.addPart("id", new StringBody(userid));
hope this helps.

Volley failing multipart form data request

I am trying to send multipart data to a server, this data includes also some images.
So i extended Request in this way:
public class MultipartImageRequest extends Request<String> {
private MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
private static final String STRING_PART_NAME = "text";
private final Response.Listener<String> mListener;
private final ArrayList<Bitmap> mFiles = new ArrayList<>();
private HashMap<String, String> mParams = new HashMap<>();
public MultipartImageRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, ArrayList<Bitmap> files, HashMap<String, String> params)
{
super(Method.POST, url, errorListener);
mListener = listener;
mFiles.addAll(files);
mParams = params;
}
private void buildMultipartEntity()
{
int i = 0;
for(Bitmap image : mFiles) {
/*Compress bitmap*/
ByteArrayOutputStream bos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 50, bos);
entityBuilder.addPart("image_" + i, new ByteArrayBody(bos.toByteArray(), "image_" + i));
i++;
}
StringBuilder paramsBuilder = new StringBuilder();
Iterator<Map.Entry<String, String>> paramIterator = mParams.entrySet().iterator();
while (paramIterator.hasNext()) {
Map.Entry<String,String> entry = paramIterator.next();
entityBuilder.addPart(entry.getKey(), new StringBody(entry.getValue(), ContentType.DEFAULT_TEXT));
}
}
#Override
public String getBodyContentType()
{
return "multipart/form-data; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError
{
buildMultipartEntity();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try
{
entityBuilder.build().writeTo(bos);
}
catch (IOException e)
{
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response)
{
return Response.success("Uploaded", getCacheEntry());
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
params.put("Content-Type","multipart/form-data; charset=utf-8");
return params;
}
#Override
protected void deliverResponse(String response)
{
mListener.onResponse(response);
}
}
The problem is that if i set as a content type application/json it works and sends data to the server, but obviously the server gives me back an error 400 because it is expecting a multipart request, rather if i set the content type as multipart/form-data; charset=utf-8 like in the code above Volley just doesn't send the request and gives me an error 500.
I am using RequestBin to check my data and it confirms what i said above.
Also i am using a Rest Client and the request is working with it and on iphone too.
I found the solution on my own, it is important to pass a boundary to the request, otherwise the server will not be able to take our parameters.
It can be done replacing this code:
public MultipartImageRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, ArrayList<Bitmap> files, HashMap<String, String> params)
{
super(Method.POST, url, errorListener);
mListener = listener;
mFiles.addAll(files);
mParams = params;
}
with this one:
public MultipartImageRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, ArrayList<Bitmap> files, HashMap<String, String> params)
{
super(Method.POST, url, errorListener);
mListener = listener;
mFiles.addAll(files);
mParams = params;
entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
entityBuilder.setBoundary(BOUNDARY);
}
and remember to set the boundary string in your Content-Type:
#Override
public String getBodyContentType()
{
return "multipart/form-data; boundary=" + BOUNDARY + "; charset=utf-8";
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
params.put("Content-Type","multipart/form-data; boundary=" + BOUNDARY + "; charset=utf-8");
return params;
}

Error trying send an image file with Volley?

I have an image that I'm trying send to my web service with others params using Volley library. The problem is I don't know how can I pass this image about the url using POST.
Looking for a solution I have founded any suggestions to use MultiPart and I'm trying implement that but still can't do this works.
I created other constructor in my Application, this constructor should receive a File but doesn't work also and HashMap doesn't accept File param
How can I do this ?
I'm trying this.
public class ApplicationController extends Request<JSONObject>{
private Map<String, String> headers;
private Map<String, String> params;
private Response.Listener<JSONObject> listener;
private File imageFile;
private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create();
public ApplicationController(String url, Map<String, String> params, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = listener;
this.params = params;
}
public ApplicationController(int method, String url, Map<String, String> params, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = listener;
this.params = params;
}
/** construtor to send image */
public ApplicationController(int method,
String url,
Map<String, String> params,
Response.Listener<JSONObject> listener,
Response.ErrorListener errorListener,
File file) {
super(method, url, errorListener);
this.listener = listener;
this.params = params;
this.imageFile = file;
}
protected Map<String, String> getParams() throws AuthFailureError {
return params;
};
public Map<String, String> getHeaders() throws AuthFailureError {
headers = new HashMap<String, String>();
String cred = String.format("%s:%s", BasicAuthenticationRest.USERNAME, BasicAuthenticationRest.PASSWORD);
String auth = "Basic " + Base64.encodeToString(cred.getBytes(), Base64.DEFAULT);
headers.put("Authorization", auth);
return headers;
};
private void buildMultipartEntity(){
mBuilder.addBinaryBody("", imageFile, ContentType.create("image/png"), imageFile.getName());
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
}
#Override
public String getBodyContentType(){
String contentTypeHeader = mBuilder.build().getContentType().getValue();
return contentTypeHeader;
}
#Override
public byte[] getBody() throws AuthFailureError{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try{
mBuilder.build().writeTo(bos);
}catch (IOException e){
VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request.");
}
return bos.toByteArray();
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
protected void deliverResponse(JSONObject response) {
listener.onResponse(response);
}
}
Using
/** add an user and upload your foto(image) */
public ApplicationController insert(Usuario u, File imageFile, final UsuarioAdapter listener){
boolean insert = false;
HashMap<String, String> params = new HashMap<String, String>();
params.put("nome", u.getNome());
params.put("email", u.getEmail());
params.put("senha", u.getSenha());
params.put("tipo", "usuarios");
params.put("acao", "add");
params.put("device_tipo", "android");
params.put("device", AndroidReturnId.getAndroidId());
params.put("uploadedfile", imageFile);
ApplicationController apc = new ApplicationController(Method.POST, urlPost.toString(), params,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject obj) {
try {
if(obj.getString("cod").equals("999")){
listener.usuarioIsAdded(true);
}else{
listener.usuarioIsAdded(false);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError arg0) {
Log.e("ERROR METHOD:", "insert in UsuarioDAO: " + arg0.getLocalizedMessage());
}
}, File file);
return apc;
}
Encode the file to a base 64 encoded string and set that in the body (just make sure your server accepts this format!). Google how to do this in java, it's everywhere
params.put("uploadedfile", base64EncodedImageFile);

Categories

Resources