I am making app in which user can attach Image from gallery, capture from camera or attach PDF file so i want to send File using volley. I wrote MultipartRequest class in which i can pass bitmap by using ByArrayOutputStream. But now i want to send File. There is an sendLeave() in fragment which Fragment which sending file with other params. Only MultipartRequest class and SendLeave() is only related code for this question but other code for how file is created.
MultipartRequest Class
public class MultipartRequest 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 MultipartRequest(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);
}
class DataPart {
private String fileName;
private byte[] content;
private String type;
public DataPart() {
}
DataPart(String name, byte[] data) {
fileName = name;
content = data;
}
String getFileName() {
return fileName;
}
byte[] getContent() {
return content;
}
String getType() {
return type;
}
}
}
AttachDocument Fragment
public class LeaveCreate extends Fragment {
File files;
@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
btnAttach.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final Dialog dialog = new Dialog(getActivity());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_layout);
dialog.show();
Button btnGallery = (Button) dialog.findViewById(R.id.btnGallery);
Button btnFile = (Button) dialog.findViewById(R.id.btnFile);
Button btnCamera = (Button) dialog.findViewById(R.id.btnCamera);
btnGallery.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.setType("image/*");
startActivityForResult(pickIntent,1);
}
});
btnFile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/pdf");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(Intent.createChooser(intent,"Select a File to Upload"),2);
}catch (android.content.ActivityNotFoundException ex){
Toast.makeText(getActivity(), "Please Install a File Manager",Toast.LENGTH_SHORT).show();
}
}
});
btnCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
String filename = "digimTemp.jpg";
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Images.Media.TITLE,filename);
mCapturedImageURI = getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,mCapturedImageURI);
startActivityForResult(cameraIntent,3);
}
});
}
});
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SendLeave();
}
});
return view;
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 1) {
if (resultCode == Activity.RESULT_OK) {
Uri selectedImageUri = data.getData();
String path = getRealPathFromURI(getActivity(),selectedImageUri);
// Toast.makeText(getBaseContext(),path,
// Toast.LENGTH_LONG).show();
files = new File(path.substring(0,path.lastIndexOf("/")),path.substring(path.lastIndexOf("/"),path.length()));
btnAttach.setText("Gallery");
Bitmap b = null;
try {
b = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), selectedImageUri);
} catch (IOException e) {
e.printStackTrace();
}
Drawable d = new BitmapDrawable(getResources(), b);
d.setBounds(0, 0, 60, 60);
btnAttach.setCompoundDrawables(d, null, null, null);
btnAttach.setCompoundDrawablePadding(20);
}
}
else if (requestCode == 2) {
if (resultCode == Activity.RESULT_OK) {
Uri selectedImageUri = data.getData();
String path = null;
path = getPath(getActivity(),selectedImageUri);
Toast.makeText(getActivity().getBaseContext(),path,
Toast.LENGTH_LONG).show();
files = new File(path.substring(0,path.lastIndexOf("/")),path.substring(path.lastIndexOf("/"),path.length()));
btnAttach.setText(path.substring(path.lastIndexOf("/")+1,path.length()));
}
}
else if(requestCode == 3)
{
if (resultCode == Activity.RESULT_OK) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection, null, null, null);
int column_index_data = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToLast();
String path = cursor.getString(column_index_data);
Bitmap photo = BitmapFactory.decodeFile(path);
// CALL THIS METHOD TO GET THE URI FROM THE BITMAP
// Uri tempUri = getImageUri(getApplicationContext(), bitmap);
files = new File(path.substring(0,path.lastIndexOf("/")),path.substring(path.lastIndexOf("/"),path.length()));
if (Integer.parseInt(String.valueOf(files.length() / 1024)) > 100) {
// filesize=String.valueOf(files.length()/1048576)+" MB";
}
btnAttach.setText("Camera");
// attachment.setDrawableLe
Drawable d = new BitmapDrawable(getResources(), photo);
d.setBounds(0, 0, 60, 60);
btnAttach.setCompoundDrawables(d, null, null, null);
btnAttach.setCompoundDrawablePadding(20);
}
}
}
}
public void SendLeave(){
progressDialog.show();
MultipartRequest multipartRequest = new MultipartRequest(Request.Method.POST, SEND_LEAVE_URL, new Response.Listener<NetworkResponse>() {
@Override
public void onResponse(NetworkResponse response) {
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("parent_id", SharedPreferenceManager.getmInstance(getActivity()).getID());
params.put("student_id",studentid);
params.put("reason",txtReason.getText().toString());
params.put("start_date",txtFromDate.getText().toString());
params.put("end_date",txtToDate.getText().toString());
int i=0;
for (String temp: teacherid){
params.put("teacher_id["+(i++)+"]", temp);
}
return params;
}
@Override
protected Map<String, MultipartRequest.DataPart> getByteData() {
Map<String, MultipartRequest.DataPart> params = new HashMap<>();
params.put("file", new MultipartRequest.DataPart());
return params;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> headers = super.getHeaders();
if (headers == null || headers.equals(Collections.<String, String>emptyMap())){
headers = new HashMap<String, String>();
}
MyApp.get().addSessionCookie(headers);
return headers;
}
};
RequestQueue queue = Volley.newRequestQueue(getContext());
queue.add(multipartRequest);
}