How to post audio and image as multipart/formdata in native android?

I want to post Form Data like this,

enter image description here

where,

  1. ApiKey, userid, albumid, music_name, singer_name are the keys whose corresponding values are all text type.
  2. music_cover and music_file are the keys for image file and audio file as their value.

All the values are non nullable. That is, must pass all values to the server to get a success response.

So, all in all, I have a bunch of texts and an audio and an image to upload to server using web service from android.

I am picking the image and audio using picker, so I have their file path.

Please guide me through the process of uploading audio and image using multipart from android.

It has kept me up all night and yet no reprieve.

Upvotes: 0

Views: 1972

Answers (1)

Jay Thummar
Jay Thummar

Reputation: 2299

Here I created an example using Volley So first of all we have to build a RestApiMultiPartRequests.class so here i created it like this

private class RestApiMultiPartRequests extends Request {

private final Map<String, String> mStringParts;
private final Map<String, File> mFileParts;
private MultipartEntityBuilder mBuilder;
private final Response.Listener<T> mListener;

public RestApiMultiPartRequests(String url,
                                Map<String, String> stringParts,
                                Map<String, File> fileParts,
                                Response.Listener<T> listener,
                                Response.ErrorListener errorListener) {
    super(Method.POST, url, errorListener);
    mListener = listener;
    mStringParts = stringParts;
    mFileParts = fileParts;
    buildMultipartEntity();
}

private void buildMultipartEntity() {
    if (mBuilder != null) {
        mBuilder = null;
    }
    mBuilder = MultipartEntityBuilder.create();
    mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
    mBuilder.setBoundary("_____" + Long.toString(System.currentTimeMillis()) + "_____");
    mBuilder.setCharset(Consts.UTF_8);
    if (mStringParts != null) {
        for (Map.Entry<String, String> entry : mStringParts.entrySet()) {
            mBuilder.addTextBody(entry.getKey(), entry.getValue(), ContentType.create("text/plain", Charset.forName("UTF-8")));
        }
    }

    Log.e("Size", "Size: " + mFileParts.size());
    for (Map.Entry<String, File> entry : mFileParts.entrySet()) {
        ContentType imageContentType = ContentType.create("image/*");//MULTIPART_FORM_DATA;
        Log.d("", "Key " + entry.getKey());
        Log.d("", "Value " + entry.getValue());
        Log.d("", "Name " + entry.getValue().getName());
        //"userfile"
        mBuilder.addBinaryBody(entry.getKey(), entry.getValue(), imageContentType, entry.getValue().getName());
    }
}

@Override
public String getBodyContentType() {
    return mBuilder.build().getContentType().getValue();
}

@Override
public byte[] getBody() {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
        mBuilder.build().writeTo(bos);
    } catch (IOException e) {
        e.printStackTrace();
    }

    return bos.toByteArray();
}


public HttpEntity getEntity() {
    return mBuilder.build();
}


@SuppressWarnings("unchecked")
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
    try {
        String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        return (Response<T>) Response.success(jsonString, HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
    }
}

@Override
protected void deliverResponse(T response) {
    mListener.onResponse(response);

}


}

Using this class we can build a request like this

 private void UploadImage() {

    ServiceCall.RestApiMultiPartRequests<String> restApiMultiPartRequest =
            new ServiceCall.RestApiMultiPartRequests<String>(url/*YOUR SERVICE URL*/, hashMap /* HASHMAP OF STRING */, fileparts  /*HASH MAP OF FILE AND STRING */, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                   /*   HANDEL YOUR SUCCESS RESPONSE **/
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // Handle your error types accordingly.For Timeout & No
                    // connection error, you can show 'retry' button.
                    // For AuthFailure, you can re login with user
                    // credentials.
                    // For ClientError, 400 & 401, Errors happening on
                    // client side when sending api request.
                    // In this case you can check how client is forming the
                    // api and debug accordingly.
                    // For ServerError 5xx, you can do retry or handle
                    // accordingly.


                      /**  HANDLE YOUR ERRORS */
                }
            }) {

                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    Map<String, String> params = new HashMap<String, String>();
                    params.put("Authorization","YOUR AUTHANTICATION TOKEN IF REQUIRED");
                    return params;
                }

                @Override
                protected Map<String, String> getParams() throws AuthFailureError {
                    Map<String, String> params = new HashMap<String, String>();
                    return params;
                }
            };

    restApiMultiPartRequest.setRetryPolicy(new DefaultRetryPolicy(0, 1, 2));//10000
    VOLLEY_INSTANCE.addToRequestQueue(restApiMultiPartRequest);
}

Here hashmap is HashMap<String, String> hashMap and fileparts is HashMap<String, File> fileparts;

so the parameters with String key and String value add in to hashmap and parameters with String key and File Value add into fileparts

Upvotes: 1

Related Questions