Gradle:
implementation 'com.mcxiaoke.volley:library:1.0.18'
VolleyMultipartRequest.java
import com.android.volley.AuthFailureError;
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 java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
public class VolleyMultipartRequest extends Request<NetworkResponse> {
private final String twoHyphens = "--";
private final String lineEnd = "\r\n";
private final String boundary = "apiclient-" + System.currentTimeMillis();
private Response.Listener<NetworkResponse> mListener;
private Response.ErrorListener mErrorListener;
private Map<String, String> mHeaders;
public VolleyMultipartRequest(int method, String url,
Response.Listener<NetworkResponse> listener,
Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
}
@Override public Map<String, String> getHeaders() throws AuthFailureError {
return (mHeaders != null) ? mHeaders : super.getHeaders();
}
@Override public String getBodyContentType() {
return "multipart/form-data;boundary=" + boundary;
}
@Override public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
try {
// populate text payload Map<String, String> params = getParams();
if (params != null && params.size() > 0) {
textParse(dos, params, getParamsEncoding());
}
// populate data byte payload Map<String, DataPart> data = getByteData();
if (data != null && data.size() > 0) {
dataParse(dos, data);
}
// close multipart form data after text and file data dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/** * Custom method handle data payload. *
* @return Map data part label with data byte
* @throws AuthFailureError
*/ protected Map<String, DataPart> getByteData() throws AuthFailureError {
return null;
}
@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);
}
/** * Parse string map into data output stream by key and value.
* * @param dataOutputStream data output stream handle string parsing
* @param params string inputs collection
* @param encoding encode the inputs, default UTF-8
* @throws IOException */
private void textParse(DataOutputStream dataOutputStream, Map<String, String> params, String encoding) throws IOException {
try {
for (Map.Entry<String, String> entry : params.entrySet()) {
buildTextPart(dataOutputStream, entry.getKey(), entry.getValue());
}
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + encoding, uee);
}
}
/** * Parse data into data output stream. * * @param dataOutputStream data output stream handle file attachment
* @param data
loop through data
* @throws IOException
*/ private void dataParse(DataOutputStream dataOutputStream, Map<String, DataPart> data) throws IOException {
for (Map.Entry<String, DataPart> entry : data.entrySet()) {
buildDataPart(dataOutputStream, entry.getValue(), entry.getKey());
}
}
/** * Write string data into header and data output stream. *
* @param dataOutputStream data output stream handle string parsing
* @param parameterName name of input
* @param parameterValue value of input
* @throws IOException */
private void buildTextPart(DataOutputStream dataOutputStream, String parameterName, String parameterValue) throws IOException {
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + parameterName + "\"" + lineEnd);
dataOutputStream.writeBytes(lineEnd);
dataOutputStream.writeBytes(parameterValue + lineEnd);
}
/** * Write data file into header and data output stream. * * @param dataOutputStream data output stream handle data parsing
* @param dataFile
data byte as DataPart from collection
* @param inputName name of data input
* @throws IOException */
private void buildDataPart(DataOutputStream dataOutputStream, DataPart dataFile, String inputName) throws IOException {
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" +
inputName + "\"; filename=\"" + dataFile.getFileName() + "\"" + lineEnd);
if (dataFile.getType() != null && !dataFile.getType().trim().isEmpty()) {
dataOutputStream.writeBytes("Content-Type: " + dataFile.getType() + lineEnd);
}
dataOutputStream.writeBytes(lineEnd);
ByteArrayInputStream fileInputStream = new ByteArrayInputStream(dataFile.getContent());
int bytesAvailable = fileInputStream.available();
int maxBufferSize = 1024 * 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
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);
}
public class DataPart {
private String fileName;
private byte[] content;
private String type;
public DataPart() {
}
public DataPart(String name, byte[] data) {
fileName = name;
content = data;
}
String getFileName() {
return fileName;
}
byte[] getContent() {
return content;
}
String getType() {
return type;
}
}
}
Method for uploading.
private void uploadBitmap(Bitmap bitmap) {
progressDialog = new ProgressDialog(Account.this);
progressDialog.setMessage("Loading...");
progressDialog.show();
// Bitmap bitmap1 = search_earn_money8.getDrawingCache();
final String imageOne = getStringImage(bitmaps); // get base64 encoded string.
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
@Override public void onResponse(String response) {
progressDialog.dismiss();
Log.v("LOG_VOLLEY", response);
System.out.println("response"+response);
try {
JSONObject jsonResponse = new JSONObject(response);
String stauts=jsonResponse.getString("success");
System.out.println("naveen is in"+stauts);
if(stauts.equals("1"))
{
Toast.makeText(Account.this,""+jsonResponse.getString("message"),Toast.LENGTH_LONG).show();
}
else if(stauts.equals("0"))
{
Toast.makeText(Account.this,"Error!",Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Log.e("LOG_VOLLEY", error.toString());
}
}) {
@Override protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("uid", uid);
params.put("img", imageOne);
return params;
}
};
stringRequest.setRetryPolicy(new RetryPolicy() {
@Override public int getCurrentTimeout() {
return 50000;
}
@Override public int getCurrentRetryCount() {
return 50000;
}
@Override public void retry(VolleyError error) throws VolleyError {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
public String getStringImage(Bitmap bmp) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage;
}