Skip to content Skip to sidebar Skip to footer

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?"