How To Send Multipart Request Using Volley Without Httpentity?
I am following the solution to send multi-part request using volley from How to multipart data using Android Volley. But, since SDK 22, httpentity is deprecated and it's removed co
Solution 1:
I have found a solution for this (based on Multipart/form-data requests in Android: HttpURLConnection vs OkHttp )
Here is my working sample code (tested with ASP.Net WebAPI)
MultipartActivity.java
package com.example.volleyapp;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.view.Menu;
import android.view.MenuItem;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.example.volleyapp.BaseVolleyRequest;
import com.example.volleyapp.VolleySingleton;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
publicclassMultipartActivityextendsActivity {
finalContextmContext=this;
String mimeType;
DataOutputStreamdos=null;
StringlineEnd="\r\n";
Stringboundary="apiclient-" + System.currentTimeMillis();
StringtwoHyphens="--";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
intmaxBufferSize=1024 * 1024;
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_multipart);
Drawabledrawable= ContextCompat.getDrawable(mContext, R.drawable.ic_action_file_attachment_light);
Bitmapbitmap= ((BitmapDrawable) drawable).getBitmap();
ByteArrayOutputStreambyteArrayOutputStream=newByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
finalbyte[] bitmapData = byteArrayOutputStream.toByteArray();
Stringurl="http://192.168.1.100/api/postfile";
mimeType = "multipart/form-data;boundary=" + boundary;
BaseVolleyRequestbaseVolleyRequest=newBaseVolleyRequest(1, url, newResponse.Listener<NetworkResponse>() {
@OverridepublicvoidonResponse(NetworkResponse response) {
}
}, newResponse.ErrorListener() {
@OverridepublicvoidonErrorResponse(VolleyError error) {
}
}) {
@Overridepublic String getBodyContentType() {
return mimeType;
}
@Overridepublicbyte[] getBody() throws AuthFailureError {
ByteArrayOutputStreambos=newByteArrayOutputStream();
dos = newDataOutputStream(bos);
try {
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
+ "ic_action_file_attachment_light.png" + "\"" + lineEnd);
dos.writeBytes(lineEnd);
ByteArrayInputStreamfileInputStream=newByteArrayInputStream(bitmapData);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = newbyte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return bitmapData;
}
};
VolleySingleton.getInstance(mContext).addToRequestQueue(baseVolleyRequest);
}
@OverridepublicbooleanonCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_multipart, menu);
returntrue;
}
@OverridepublicbooleanonOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.intid= item.getItemId();
//noinspection SimplifiableIfStatementif (id == R.id.action_settings) {
returntrue;
}
returnsuper.onOptionsItemSelected(item);
}
}
BaseVolleyRequest.java:
package com.example.volleyapp;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.JsonSyntaxException;
publicclassBaseVolleyRequestextendsRequest<NetworkResponse> {
privatefinal Response.Listener<NetworkResponse> mListener;
privatefinal Response.ErrorListener mErrorListener;
publicBaseVolleyRequest(String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
super(0, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
}
publicBaseVolleyRequest(int method, String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
}
@Overrideprotected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
try {
return Response.success(
response,
HttpHeaderParser.parseCacheHeaders(response));
} catch (JsonSyntaxException e) {
return Response.error(newParseError(e));
} catch (Exception e) {
return Response.error(newParseError(e));
}
}
@OverrideprotectedvoiddeliverResponse(NetworkResponse response) {
mListener.onResponse(response);
}
@Overrideprotected VolleyError parseNetworkError(VolleyError volleyError) {
returnsuper.parseNetworkError(volleyError);
}
@OverridepublicvoiddeliverError(VolleyError error) {
mErrorListener.onErrorResponse(error);
}
}
Solution 2:
Use following in your build.gradle
android {
useLibrary 'org.apache.http.legacy'
}
See http://developer.android.com/preview/behavior-changes.html#behavior-apache-http-client
Post a Comment for "How To Send Multipart Request Using Volley Without Httpentity?"