5

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 completely on SDK 23.

The solution is to use openConnection, just like HttpEntity is deprecated on Android now, what's the alternative?, but I don't know how to use it for multi-part request

0

2 Answers 2

3

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; public class MultipartActivity extends Activity { final Context mContext = this; String mimeType; DataOutputStream dos = null; String lineEnd = "\r\n"; String boundary = "apiclient-" + System.currentTimeMillis(); String twoHyphens = "--"; int bytesRead, bytesAvailable, bufferSize; byte[] buffer; int maxBufferSize = 1024 * 1024; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_multipart); Drawable drawable = ContextCompat.getDrawable(mContext, R.drawable.ic_action_file_attachment_light); Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream); final byte[] bitmapData = byteArrayOutputStream.toByteArray(); String url = "http://192.168.1.100/api/postfile"; mimeType = "multipart/form-data;boundary=" + boundary; BaseVolleyRequest baseVolleyRequest = new BaseVolleyRequest(1, url, new Response.Listener<NetworkResponse>() { @Override public void onResponse(NetworkResponse response) { } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } }) { @Override public String getBodyContentType() { return mimeType; } @Override public byte[] getBody() throws AuthFailureError { ByteArrayOutputStream bos = new ByteArrayOutputStream(); dos = new DataOutputStream(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); ByteArrayInputStream fileInputStream = new ByteArrayInputStream(bitmapData); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[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); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_multipart, menu); return true; } @Override public boolean onOptionsItemSelected(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. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.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; public class BaseVolleyRequest extends Request<NetworkResponse> { private final Response.Listener<NetworkResponse> mListener; private final Response.ErrorListener mErrorListener; public BaseVolleyRequest(String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) { super(0, url, errorListener); this.mListener = listener; this.mErrorListener = errorListener; } public BaseVolleyRequest(int method, String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) { super(method, url, errorListener); this.mListener = listener; this.mErrorListener = errorListener; } @Override protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) { try { return Response.success( response, HttpHeaderParser.parseCacheHeaders(response)); } catch (JsonSyntaxException e) { return Response.error(new ParseError(e)); } catch (Exception e) { return Response.error(new ParseError(e)); } } @Override protected void deliverResponse(NetworkResponse response) { mListener.onResponse(response); } @Override protected VolleyError parseNetworkError(VolleyError volleyError) { return super.parseNetworkError(volleyError); } @Override public void deliverError(VolleyError error) { mErrorListener.onErrorResponse(error); } } 
Sign up to request clarification or add additional context in comments.

5 Comments

Hello, first thank you for your example ! I'm trying to put de method de getParams but it is not called, have you a solution ?
@Spierki As you can see I use getBody(), not getParams
Yes I see I used the getBody to put my files but if I need to put other params in a hashmap, I need to put them in this method too ? Or is there a solution for getParams to be called ?
@Spierki you can refer to textPart at my following link stackoverflow.com/questions/32240177/…
@BNK i want insert feild name to send server where it is i put in your code like "ProfileImg"?
1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.