this is FileUploadMultipartRequest class:
/**
* Multipart request for sending files over http
* also can return generic type of response data
* @param <T> the type of data for http responses
*/
public class FileUploadMultipartRequest<T> extends BaseRequest<T>
{
private static final MediaType JSON = MediaType.parse("application/json");
private File[] files;
private String jsonString;
private RequestBody requestBody;
public FileUploadMultipartRequest(String url, Map<String, String> headers, String jsonString, OnEmptyResponseListener listener, ErrorTypeListener errorListener, File... files)
{
super(Method.POST, url, headers, listener, new ErrorListenerImpl(errorListener));
this.jsonString = jsonString;
this.files = files;
}
public FileUploadMultipartRequest(String url, Map<String, String> headers, String jsonString, Type responseType, Response.Listener listener, ErrorTypeListener errorListener, File... files)
{
super(Method.POST, url, headers, responseType, listener, new ErrorListenerImpl(errorListener));
this.jsonString = jsonString;
this.files = files;
}
@Override
public String getBodyContentType()
{
return buildMultipartEntity().contentType().toString();
}
@Override
public byte[] getBody() throws AuthFailureError
{
Buffer buffer = new Buffer();
try
{
buildMultipartEntity().writeTo(buffer);
} catch (IOException e)
{
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return buffer.readByteArray();
}
private RequestBody buildMultipartEntity()
{
if (requestBody == null)
{
MultipartBuilder multipartBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);
multipartBuilder.addPart(
Headers.of("Content-Disposition", "form-data; name=json-part"),
RequestBody.create(JSON, jsonString));
for (File file : files)
{
String contentType = URLConnection.guessContentTypeFromName(file.getName());
multipartBuilder.addFormDataPart("files-part", file.getName(),
RequestBody.create(MediaType.parse(contentType), file));
}
requestBody = multipartBuilder.build();
}
return requestBody;
}
}
this is BaseRequest class:
/**
* this a abstract request class for handling http http responses
* note : all volley request should extend this class for http request
*
* @param <T> the type of data for http responses
*/
public abstract class BaseRequest<T> extends Request<T>
{
private final Map<String, String> headers;
/**
* the type response that {@link com.android.volley.Response.Listener} should return
*/
private Type responseType;
/**
* generic listener for successful http request
*/
private Response.Listener<T> listener;
/**
* constructor for request that returns data type {@link T}
*
* @param method http verb e.g. POST, GET & etc
* @param url request URL
* @param headers http headers
* @param responseType type of data that response should return
* @param listener event for successful request
* @param errorListener event for failed request
*/
public BaseRequest(int method, String url, Map<String, String> headers, Type responseType, Response.Listener listener, ErrorListenerImpl errorListener)
{
super(method, url, errorListener);
this.headers = headers;
this.responseType = responseType;
//noinspection unchecked
this.listener = listener;
}
/**
* constructor for requests with no returning data
* @param method http verb e.g. POST, GET & etc
* @param url request URL
* @param headers http headers
* @param onEmptyResponseListener event for successful request (but no data return)
* @param errorListener event for failed request
*/
public BaseRequest(int method, String url, Map<String, String> headers, OnEmptyResponseListener onEmptyResponseListener, ErrorListenerImpl errorListener)
{
super(method, url, errorListener);
this.headers = headers;
//noinspection unchecked
listener = new OnEmptyResponseImpl(onEmptyResponseListener);
}
protected Response<T> parseNetworkResponse(NetworkResponse response)
{
// if response type is null so just pass null to success event
if (this.responseType == null && new String(response.data).isEmpty())
{
return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
}
// if response type is specified
try
{
Gson gson = new Gson();
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
// we use GSON to reflect response data to the generic type and pass to success event
T parseObject = gson.fromJson(json, responseType);
return Response.success(parseObject, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e)
{
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e)
{
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(T response)
{
if (listener != null)
{
// call successful response event when listener not empty
listener.onResponse(response);
}
}
@Override
protected void onFinish()
{
super.onFinish();
listener = null;
}
/**
* this class forward response event to {@link com.khosravi.mehrdadz.garagesale.Network.RequestType.BaseRequest.OnEmptyResponseListener}
* when volley {@link com.android.volley.Response.Listener} is called
*/
private static class OnEmptyResponseImpl implements Response.Listener
{
OnEmptyResponseListener onEmptyResponseListener;
/**
* @param onEmptyResponseListener interface for response with not data return
*/
public OnEmptyResponseImpl(OnEmptyResponseListener onEmptyResponseListener)
{
this.onEmptyResponseListener = onEmptyResponseListener;
}
/**
* we call {@link com.khosravi.mehrdadz.garagesale.Network.RequestType.BaseRequest.OnEmptyResponseImpl#onEmptyResponseListener}
* when volley listener is class so no null object passed to the event
*
* @param response
*/
@Override
public void onResponse(Object response)
{
onEmptyResponseListener.OnEmptyResponse();
}
}
/**
* interface for http response with no returning data
*/
public interface OnEmptyResponseListener
{
void OnEmptyResponse();
}
public Map<String, String> getHeaders() throws AuthFailureError
{
return this.headers != null ? this.headers : super.getHeaders();
}
}
and this is GsonRequest class:
@SuppressWarnings("JavaDoc")
/**
* Gson request that return generic type of response data
* @param <T> the type of data for http responses
*/
public class GsonRequest<T> extends BaseRequest<T>
{
protected static final String PROTOCOL_CHARSET = "utf-8";
/**
* Content type for request.
*/
private static final String PROTOCOL_CONTENT_TYPE =
String.format("application/json; charset=%s", PROTOCOL_CHARSET);
/**
* message body of http request
*/
private final String requestBody;
/**
* Request return response object of Type {@link T}
* @param url
* @param headers
* @param type
* @param listener
* @param errorListener
*/
public GsonRequest(String url, Map<String, String> headers, Type type, Listener<T> listener, ErrorTypeListener errorListener)
{
super(Method.GET, url, headers, type, listener, new ErrorListenerImpl(errorListener));
requestBody = null;
}
/**
* Request return response object of Type {@link T}
* @param url
* @param headers
* @param jsonObject json object to send with request
* @param type
* @param listener
* @param errorListener
*/
public GsonRequest(String url, Map<String, String> headers, JSONObject jsonObject, Type type, Listener<T> listener, ErrorTypeListener errorListener)
{
super(Method.POST, url, headers, type, listener, new ErrorListenerImpl(errorListener));
this.requestBody = jsonObject == null ? null : jsonObject.toString();
}
/**
* Request return empty response
* @param url
* @param headers
* @param jsonObject json object to send with request
* @param listener
* @param errorListener
*/
public GsonRequest(String url, Map<String, String> headers, JSONObject jsonObject, OnEmptyResponseListener listener, ErrorTypeListener errorListener)
{
super(Method.POST, url, headers, listener, new ErrorListenerImpl(errorListener));
this.requestBody = jsonObject == null ? null : jsonObject.toString();
}
/**
* Request return empty response
* @param url
* @param headers
* @param listener
* @param errorListener
*/
public GsonRequest(String url, Map<String, String> headers, BaseRequest.OnEmptyResponseListener listener, ErrorTypeListener errorListener)
{
super(Method.GET, url, headers, listener, new ErrorListenerImpl(errorListener));
requestBody = null;
}
@Override
public String getBodyContentType()
{
return PROTOCOL_CONTENT_TYPE;
}
@Override
public byte[] getBody()
{
try
{
return requestBody == null ? null : requestBody.getBytes(PROTOCOL_CHARSET);
} catch (UnsupportedEncodingException uee)
{
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
requestBody, PROTOCOL_CHARSET);
return null;
}
}
}
sample cod:
public class MyRequest
{
public MyRequest(Context context)
{
volleySingleton = VolleySingleton.getInstance(context);
}
private static final String INSERT_NEW_PIC = "INSERT_NEW_PIC";
public void UploadNewPic(File[] Images, BaseRequest.OnEmptyResponseListener listener, ErrorTypeListener errorListener)
{
FileUploadMultipartRequest fileUploadMultipartRequest = new FileUploadMultipartRequest("url", null, null, listener, errorListener,Images);
volleySingleton.addToRequestQueue(fileUploadMultipartRequest, INSERT_NEW_PIC);
}
}
you can add more request to my request and call that anywhere.
like this:
MyRequest myRequest;
private HashMap<FrameLayout,File> Images;
myRequest = new MyRequest(context);
Images = new HashMap<>();
myRequest.UploadNewPic(Images.values().toArray(new File[Images.values().size()]), new BaseRequest.OnEmptyResponseListener()
{
@Override