Post multipart request with Android SDK
Asked Answered
W

12

82

I'm trying to do something I thought would be relatively simple: Upload an image to a server with the Android SDK. I'm found a lot of example code:

http://groups.google.com/group/android-developers/browse_thread/thread/f9e17bbaf50c5fc/46145fcacd450e48

http://linklens.blogspot.com/2009/06/android-multipart-upload.html

But neither work for me. The confusion I keep running into is what is really needed to make a multipart request. What is the simplest way to have a multipart upload (with an image) for Android?

Any help or advice would be greatly appreciated!

Weatherglass answered 7/1, 2010 at 0:34 Comment(3)
What are the problems you're having with the methods you've tried so far?Deledda
Oh lots of problems. Currently getting the photo uri passed back from the photo picker into a file I can attach to a MultipartEntity. But I'm not even sure this is the correct way to construct a multiport request.Weatherglass
This is really old. Someone needs to answer this with modern libraries, or at least post code that works! So many things have been deprecated in the decade since this question was asked, I'm having a hard time finding something that even compiles.Lattimer
F
104

Update April 29th 2014:

My answer is kind of old by now and I guess you rather want to use some kind of high level library such as Retrofit.


Based on this blog I came up with the following solution: http://blog.tacticalnuclearstrike.com/2010/01/using-multipartentity-in-android-applications/

You will have to download additional libraries to get MultipartEntity running!

1) Download httpcomponents-client-4.1.zip from http://james.apache.org/download.cgi#Apache_Mime4J and add apache-mime4j-0.6.1.jar to your project.

2) Download httpcomponents-client-4.1-bin.zip from http://hc.apache.org/downloads.cgi and add httpclient-4.1.jar, httpcore-4.1.jar and httpmime-4.1.jar to your project.

3) Use the example code below.

private DefaultHttpClient mHttpClient;


public ServerCommunication() {
    HttpParams params = new BasicHttpParams();
    params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
    mHttpClient = new DefaultHttpClient(params);
}


public void uploadUserPhoto(File image) {

    try {

        HttpPost httppost = new HttpPost("some url");

        MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);  
        multipartEntity.addPart("Title", new StringBody("Title"));
        multipartEntity.addPart("Nick", new StringBody("Nick"));
        multipartEntity.addPart("Email", new StringBody("Email"));
        multipartEntity.addPart("Description", new StringBody(Settings.SHARE.TEXT));
        multipartEntity.addPart("Image", new FileBody(image));
        httppost.setEntity(multipartEntity);

        mHttpClient.execute(httppost, new PhotoUploadResponseHandler());

    } catch (Exception e) {
        Log.e(ServerCommunication.class.getName(), e.getLocalizedMessage(), e);
    }
}

private class PhotoUploadResponseHandler implements ResponseHandler<Object> {

    @Override
    public Object handleResponse(HttpResponse response)
            throws ClientProtocolException, IOException {

        HttpEntity r_entity = response.getEntity();
        String responseString = EntityUtils.toString(r_entity);
        Log.d("UPLOAD", responseString);

        return null;
    }

}
Fulgurate answered 7/3, 2011 at 14:37 Comment(17)
I can't find the MultipartEntity as well as HttpMultipartClient library in Android. Could you help me please?Donor
this is the correct answer. it's a shame that this class isn't included in the Android SDK.Incivility
Why do you need apache-mime4j-0.6.1.jar?Olecranon
Works perfectly - I only needed to add the httpmime-4.1.jar (apparently httpmime-4.2.jar)Instar
how big is this library? I don't want to commit to using a full library for 1 classMonteiro
It worked like a charm. For those who didn't get expected result: if back-end developers tells you to upload photo under name "uploadFileName" please ask for server-side code snippet or html form to verify. I was struggling 3 hours and file was not uploaded, and finally backend guys showed me code and I found out that I just should use another property name...F
Works like a charm, except now the ADT debugger is throwing ClassNotFoundException. I'm assuming I need to tell it to send the additional jars to the phone I'm debugging on (some old HTC), any idea on how to do that?Marlea
This really helped me a lot; I replaced a LOT of manual InputStream/OutputStream code, as well as HTTPS handling, by using these classes instead. 40 execution lines (excluding adding parameters) down to 2, plus a reusable multithreaded ResponseHandler!Corrie
anyone looking for this now first set of files are now here : psg.mtu.edu/pub/apache//james/mime4jCoexist
Thanks for the solution. However, MultipartEntityis deprecated now. This post may guide those looking to use MultipartEntityBuilder instead: https://mcmap.net/q/244452/-upload-a-file-through-an-http-form-via-multipartentitybuilder-with-a-progress-barFagot
There are a lot of answers out there that claim to be correct but this one is def it. Ty TyKarinkarina
Are you sure httpClient jar needs to be added?Gery
I'm not sure if there isn't a more elegant solution to this issue yet!? My answer now dates back 3 years already.Fulgurate
use compile 'org.apache.httpcomponents:httpmime:4.3.4' compile 'org.apache.httpcomponents:httpcore:4.3.2' for android studio dependenciesFaery
@Fulgurate can I get some sample code of retrofit for post, get, multipart upload file with progress?Prae
sorry, but I don't have any sample code for retrofitFulgurate
Many people has suggested that it is deprecated now.Then how can I post any File to server using Multipart.Jacobjacoba
G
48

As MultiPartEntity is deprecated. So here is the new way to do it! And you only need httpcore.jar(latest) and httpmime.jar(latest) download them from Apache site.

try
{
    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost(URL);

    MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
    entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

    entityBuilder.addTextBody(USER_ID, userId);
    entityBuilder.addTextBody(NAME, name);
    entityBuilder.addTextBody(TYPE, type);
    entityBuilder.addTextBody(COMMENT, comment);
    entityBuilder.addTextBody(LATITUDE, String.valueOf(User.Latitude));
    entityBuilder.addTextBody(LONGITUDE, String.valueOf(User.Longitude));

    if(file != null)
    {
        entityBuilder.addBinaryBody(IMAGE, file);
    }

    HttpEntity entity = entityBuilder.build();
    post.setEntity(entity);
    HttpResponse response = client.execute(post);
    HttpEntity httpEntity = response.getEntity();
    result = EntityUtils.toString(httpEntity);
    Log.v("result", result);
}
catch(Exception e)
{
    e.printStackTrace();
}
Gery answered 2/4, 2014 at 6:27 Comment(9)
+1 for using the Builder, because the direct instantiation is deprecated.Decastro
@muhammad babar can you tell me how if I want to upload multiple Image using MultipartEntityBuilder?Jobi
inside a loop and then entityBuilder.addBinaryBody(key, file); make sure key is unique.Gery
use compile 'org.apache.httpcomponents:httpmime:4.3.4' compile 'org.apache.httpcomponents:httpcore:4.3.2' for android studio dependenciesFaery
@MuhammadBabar It throws error on these two lines HttpEntity entity = entityBuilder.build(); post.setEntity(entity);Sidonius
@MuhammadBabar check new question #30112251Sidonius
@droid_dev please try to use my code and let me know if error persists?Gery
@droid_dev seems like you missing some jar. https://mcmap.net/q/242040/-post-multipart-request-with-android-sdk check this and put in all the jars mentioned.Gery
@MuhammadBabar Still same result. I've added other jars as well but still it throws the same errorSidonius
A
16

Here is the LIGHT WEIGHTED solution which worked for me with no external HTTPCore and such libs. I was facing issue of 64K methods so have no option left to avoid HTTPCore libraries

import java.util.List;

import java.io.BufferedReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

/**
 * This utility class provides an abstraction layer for sending multipart HTTP
 * POST requests to a web server.
 *
 * @author www.codejava.net
 */
public class MultipartUtility {
    private final String boundary;
    private static final String LINE_FEED = "\r\n";
    private HttpURLConnection httpConn;
    private String charset;
    private OutputStream outputStream;
    private PrintWriter writer;

    /**
     * This constructor initializes a new HTTP POST request with content type
     * is set to multipart/form-data
     *
     * @param requestURL
     * @param charset
     * @throws IOException
     */
    public MultipartUtility(String requestURL, String charset)
            throws IOException {
        this.charset = charset;

        // creates a unique boundary based on time stamp
        boundary = "===" + System.currentTimeMillis() + "===";

        URL url = new URL(requestURL);
        httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setUseCaches(false);
        httpConn.setDoOutput(true); // indicates POST method
        httpConn.setDoInput(true);
        httpConn.setRequestProperty("Content-Type",
                "multipart/form-data; boundary=" + boundary);
        httpConn.setRequestProperty("User-Agent", "CodeJava Agent");
        httpConn.setRequestProperty("Test", "Bonjour");
        outputStream = httpConn.getOutputStream();
        writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
                true);
    }

    /**
     * Adds a form field to the request
     *
     * @param name  field name
     * @param value field value
     */
    public void addFormField(String name, String value) {
        writer.append("--" + boundary).append(LINE_FEED);
        writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
                .append(LINE_FEED);
        writer.append("Content-Type: text/plain; charset=" + charset).append(
                LINE_FEED);
        writer.append(LINE_FEED);
        writer.append(value).append(LINE_FEED);
        writer.flush();
    }

    /**
     * Adds a upload file section to the request
     *
     * @param fieldName  name attribute in <input type="file" name="..." />
     * @param uploadFile a File to be uploaded
     * @throws IOException
     */
    public void addFilePart(String fieldName, File uploadFile)
            throws IOException {
        String fileName = uploadFile.getName();
        writer.append("--" + boundary).append(LINE_FEED);
        writer.append(
                "Content-Disposition: form-data; name=\"" + fieldName
                        + "\"; filename=\"" + fileName + "\"")
                .append(LINE_FEED);
        writer.append(
                "Content-Type: "
                        + URLConnection.guessContentTypeFromName(fileName))
                .append(LINE_FEED);
        writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
        writer.append(LINE_FEED);
        writer.flush();

        FileInputStream inputStream = new FileInputStream(uploadFile);
        byte[] buffer = new byte[4096];
        int bytesRead = -1;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.flush();
        inputStream.close();

        writer.append(LINE_FEED);
        writer.flush();
    }

    /**
     * Adds a header field to the request.
     *
     * @param name  - name of the header field
     * @param value - value of the header field
     */
    public void addHeaderField(String name, String value) {
        writer.append(name + ": " + value).append(LINE_FEED);
        writer.flush();
    }

    /**
     * Completes the request and receives response from the server.
     *
     * @return a list of Strings as response in case the server returned
     * status OK, otherwise an exception is thrown.
     * @throws IOException
     */
    public List<String> finish() throws IOException {
        List<String> response = new ArrayList<String>();

        writer.append(LINE_FEED).flush();
        writer.append("--" + boundary + "--").append(LINE_FEED);
        writer.close();

        // checks server's status code first
        int status = httpConn.getResponseCode();
        if (status == HttpURLConnection.HTTP_OK) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    httpConn.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                response.add(line);
            }
            reader.close();
            httpConn.disconnect();
        } else {
            throw new IOException("Server returned non-OK status: " + status);
        }

        return response;
    }
}

USAGE

private void uploadMedia() {
        try {

            String charset = "UTF-8";
            File uploadFile1 = new File("/sdcard/myvideo.mp4");
            String requestURL = Data.BASE_URL+Data.URL_UPLOAD_REACTION_TEST;

            MultipartUtility multipart = new MultipartUtility(requestURL, charset);

//            multipart.addHeaderField("User-Agent", "CodeJava");
//            multipart.addHeaderField("Test-Header", "Header-Value");

            multipart.addFormField("friend_id", "Cool Pictures");
            multipart.addFormField("userid", "Java,upload,Spring");

            multipart.addFilePart("uploadedfile", uploadFile1);

            List<String> response = multipart.finish();

            Log.v("rht", "SERVER REPLIED:");

            for (String line : response) {
                Log.v("rht", "Line : "+line);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

PHP Code to accept upload

<?php

    $friend_id = $_REQUEST['friend_id'];
    $userid = $_REQUEST['userid'];

    echo 'friend_id : '.$friend_id. ' userid '.$userid;

    move_uploaded_file($_FILES['uploadedfile']['tmp_name'], "./uploads/".$_FILES["uploadedfile"]["name"]);

?>
Arbitration answered 15/4, 2016 at 5:24 Comment(3)
For this boundary my code threw 400 Bad Request boundary = "===" + System.currentTimeMillis() + "==="; Then I changed the boundary as boundary = "---" + System.currentTimeMillis(); Then the request was properly parsed at back-end.Hekker
why is this so complicated...? No exactly a question. Just annoying that it takes so much to do this in this environment.Kloof
I used this with success, but had to remove the last append(LINEFEED) in addFilePart(). Thanks.Champagne
I
6

More easy, light (32k), and many more performance:

Android Asynchronous Http Client library: http://loopj.com/android-async-http/

Implementation:

How to send a “multipart/form-data” POST in Android with Volley

Incandescent answered 18/7, 2013 at 16:28 Comment(5)
the loopj asynchttpclient lib is awesome. But it fails if you want to upload multiple files at once :SBucella
@Perroloco, you might have to up the timeout amount in order to succeed with large/multiple files. The default timeout amount might be too low. Have you tried this with a longer timeout period? Because I have successfully managed to send multiple files with loopj at once...Toluate
thanx @Chris, I tried it but it still failed.. I managed it by performing multiple requests.Bucella
loopj have no option to show progress but upload file very goodMichaella
thanks @Hpsatum search from last 6 hours end, this works well !!Nominative
C
3

Try this:

    public void SendMultipartFile() {
    Log.d(TAG, "UPLOAD: SendMultipartFile");
    DefaultHttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost( <url> );

    File file = new File("/sdcard/spider.jpg");

    Log.d(TAG, "UPLOAD: setting up multipart entity");

    MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
    Log.d(TAG, "UPLOAD: file length = " + file.length());
    Log.d(TAG, "UPLOAD: file exist = " + file.exists());

    try {
        mpEntity.addPart("datafile", new FileBody(file, "application/octet"));
        mpEntity.addPart("id", new StringBody("1"));
    } catch (UnsupportedEncodingException e1) {
        Log.d(TAG, "UPLOAD: UnsupportedEncodingException");
        e1.printStackTrace();
    }

    httppost.setEntity(mpEntity);
    Log.d(TAG, "UPLOAD: executing request: " + httppost.getRequestLine());
    Log.d(TAG, "UPLOAD: request: " + httppost.getEntity().getContentType().toString());


    HttpResponse response;
    try {
        Log.d(TAG, "UPLOAD: about to execute");
        response = httpclient.execute(httppost);
        Log.d(TAG, "UPLOAD: executed");
        HttpEntity resEntity = response.getEntity();
        Log.d(TAG, "UPLOAD: respose code: " + response.getStatusLine().toString());
        if (resEntity != null) {
            Log.d(TAG, "UPLOAD: " + EntityUtils.toString(resEntity));
        }
        if (resEntity != null) {
            resEntity.consumeContent();
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Capriccio answered 15/12, 2010 at 15:49 Comment(2)
this needs 3rd party lib like the previous exampleJoann
use compile 'org.apache.httpcomponents:httpmime:4.3.4' compile 'org.apache.httpcomponents:httpcore:4.3.2' for android studio dependenciesFaery
T
3

I highly recommend Loopj.

I have successfully used it to upload multiple files at once, including different mime types. Simply do this:

File myVideo = new File("/path/to/myvideo.mp4");
File myPic = new File("/path/to/mypic.jpg");
RequestParams params = new RequestParams();
try {
  params.put("profile_picture", myPic);
  params.put("my_video", myVideo);
} catch(FileNotFoundException e) {}

For large or many files you might have to increase the timeout amount else the default timeout is used which might be too short:

client.setTimeout(500000) //make this the appropriate timeout in milliseconds

Please see this links for a full description of loopj and how to use it, by far the easiest async http library I have come across:

http://loopj.com/android-async-http/ http://loopj.com/android-async-http/doc/com/loopj/android/http/AsyncHttpClient.html

Toluate answered 19/8, 2014 at 12:57 Comment(0)
T
2
public class Multipart{
    private final Map<String, String> headrs;
    private String url;
    private HttpURLConnection con;
    private OutputStream os;

    private String delimiter = "--";
    private String boundary = "TRR" + Long.toString(System.currentTimeMillis()) + "TRR";

    public Multipart (String url, Map<String, String> headers) {
        this.url = url;
        this.headrs = headers;
    }

    public void connectForMultipart() throws Exception {
        con = (HttpURLConnection) (new URL(url)).openConnection();
        con.setRequestMethod("POST");
        con.setDoInput(true);
        con.setDoOutput(true);
        con.setRequestProperty("Connection", "Keep-Alive");
        for (Map.Entry<String, String> entry : headrs.entrySet()) {
            con.setRequestProperty(entry.getKey(), entry.getValue());
        }
        con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        con.connect();
        os = con.getOutputStream();
    }

    public void addFormPart(String paramName, String value) throws Exception {
        writeParamData(paramName, value);
    }

    public void addFilePart(String paramName, String fileName, byte[] data) throws Exception {
        os.write((delimiter + boundary + "\r\n").getBytes());
        os.write(("Content-Disposition: form-data; name=\"" + paramName + "\"; filename=\"" + fileName + "\"\r\n").getBytes());
        os.write(("Content-Type: application/octet-stream\r\n").getBytes());
        os.write(("Content-Transfer-Encoding: binary\r\n").getBytes());
        os.write("\r\n".getBytes());

        os.write(data);

        os.write("\r\n".getBytes());
    }

    public void finishMultipart() throws Exception {
        os.write((delimiter + boundary + delimiter + "\r\n").getBytes());
    }


    public String getResponse() throws Exception {
        InputStream is = con.getInputStream();
        byte[] b1 = new byte[1024];
        StringBuffer buffer = new StringBuffer();

        while (is.read(b1) != -1)
            buffer.append(new String(b1));

        con.disconnect();

        return buffer.toString();
    }


    private void writeParamData(String paramName, String value) throws Exception {


        os.write((delimiter + boundary + "\r\n").getBytes());
        os.write("Content-Type: text/plain\r\n".getBytes());//;charset=utf-8
        os.write(("Content-Disposition: form-data; name=\"" + paramName + "\"\r\n").getBytes());
        ;
        os.write(("\r\n" + value + "\r\n").getBytes());


    }
}

Then call below

Multipart multipart = new Multipart(url__, map);
            multipart .connectForMultipart();
multipart .addFormPart(entry.getKey(), entry.getValue());
multipart .addFilePart(KeyName, "FileName", imagedata);
multipart .finishMultipart();
Theone answered 30/5, 2018 at 6:31 Comment(0)
W
2

You can you use GentleRequest, which is lightweight library for making http requests(DISCLAIMER: I am the author):

Connections connections = new HttpConnections();
Binary binary = new PacketsBinary(new 
BufferedInputStream(new FileInputStream(file)), 
   file.length());
//Content-Type is set to multipart/form-data; boundary= 
//{generated by multipart object}
MultipartForm multipart = new HttpMultipartForm(
    new HttpFormPart("user", "aplication/json", 
       new JSONObject().toString().getBytes()),
    new HttpFormPart("java", "java.png", "image/png", 
       binary.content()));
Response response = connections.response(new 
    PostRequest(url, multipart));
if (response.hasSuccessCode()) {
    byte[] raw = response.body().value();
    String string = response.body().stringValue();
    JSONOBject json = response.body().jsonValue();
 } else {

 }

Feel free to check it out: https://github.com/Iprogrammerr/Gentle-Request

Wu answered 11/11, 2018 at 22:35 Comment(1)
Like a BOSS....Insnare
M
1

Remove all your httpclient, httpmime dependency and add this dependency compile 'commons-httpclient:commons-httpclient:3.1'. This dependency has built in MultipartRequestEntity so that you can easily upload one or more files to the server

public class FileUploadUrlConnection extends AsyncTask<String, String, String> {
private Context context;
private String url;
private List<File> files;

public FileUploadUrlConnection(Context context, String url, List<File> files) {
    this.context = context;
    this.url = url;
    this.files = files;
}

@Override
protected String doInBackground(String... params) {

    HttpClient client = new HttpClient();
    PostMethod post = new PostMethod(url);
    HttpClientParams connectionParams = new HttpClientParams();

    post.setRequestHeader(// Your header goes here );

    try {
        Part[] parts = new Part[files.size()];
        for (int i=0; i<files.size(); i++) {
            Part part = new FilePart(files.get(i).getName(), files.get(i));
            parts[i] = part;
        }

        MultipartRequestEntity entity = new MultipartRequestEntity(parts, connectionParams);

        post.setRequestEntity(entity);

        int statusCode = client.executeMethod(post);
        String response = post.getResponseBodyAsString();

        Log.v("Multipart "," "+response);
        if(statusCode == 200) {
            return response;
        }
    } catch (IOException e) {
        e.printStackTrace();
    } 
 return null;
}

You can also add the request and response timeout

client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000);
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 10000);
Mundell answered 5/4, 2017 at 11:21 Comment(0)
E
0

I can recomend Ion library it use 3 dependences and you can find all three jar files at these two sites:
https://github.com/koush/ion#jars (ion and androidasync)

https://code.google.com/p/google-gson/downloads/list (gson)
try {
   Ion.with(this, "http://www.urlthatyouwant.com/post/page")
   .setMultipartParameter("field1", "This is field number 1")
   .setMultipartParameter("field2", "Field 2 is shorter")
   .setMultipartFile("imagefile",
        new File(Environment.getExternalStorageDirectory()+"/testfile.jpg"))
   .asString()
   .setCallback(new FutureCallback<String>() {
        @Override
        public void onCompleted(Exception e, String result) {
             System.out.println(result);
        }});
   } catch(Exception e) {
     // Do something about exceptions
        System.out.println("exception: " + e);
   }

this will run async and the callback will be executed in the UI thread once a response is received I strongly recomned that you go to the https://github.com/koush/ion for futher information

Emprise answered 15/10, 2015 at 19:40 Comment(0)
O
0

Here is a Simple approach if you are using the AOSP library Volley.

Extend the class Request<T> as follows-

public class MultipartRequest extends Request<String> {
    private static final String FILE_PART_NAME = "file";
    private final Response.Listener<String> mListener;
    private final Map<String, File> mFilePart;
    private final Map<String, String> mStringPart;
    MultipartEntityBuilder entity = MultipartEntityBuilder.create();
    HttpEntity httpentity;

    public MultipartRequest(String url, Response.ErrorListener errorListener,
                            Response.Listener<String> listener, Map<String, File> file,
                            Map<String, String> mStringPart) {
        super(Method.POST, url, errorListener);
        mListener = listener;
        mFilePart = file;
        this.mStringPart = mStringPart;
        entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        buildMultipartEntity();
    }

    public void addStringBody(String param, String value) {
        mStringPart.put(param, value);
    }

    private void buildMultipartEntity() {
        for (Map.Entry<String, File> entry : mFilePart.entrySet()) {
            // entity.addPart(entry.getKey(), new FileBody(entry.getValue(), ContentType.create("image/jpeg"), entry.getKey()));
            try {
                entity.addBinaryBody(entry.getKey(), Utils.toByteArray(new FileInputStream(entry.getValue())), ContentType.create("image/jpeg"), entry.getKey() + ".JPG");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        for (Map.Entry<String, String> entry : mStringPart.entrySet()) {
            if (entry.getKey() != null && entry.getValue() != null) {
                entity.addTextBody(entry.getKey(), entry.getValue());
            }
        }
    }

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

    @Override
    public byte[] getBody() throws AuthFailureError {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            httpentity = entity.build();
            httpentity.writeTo(bos);
        } catch (IOException e) {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        Log.d("Response", new String(response.data));
        return Response.success(new String(response.data), getCacheEntry());
    }

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

You can create and add a request like-

Map<String, String> params = new HashMap<>();
        params.put("name", name.getText().toString());
        params.put("email", email.getText().toString());
        params.put("user_id", appPreferences.getInt( Utils.PROPERTY_USER_ID, -1) + "");
        params.put("password", password.getText().toString());
        params.put("imageName", pictureName);
        Map<String, File> files = new HashMap<>();
        files.put("photo", new File(Utils.LOCAL_RESOURCE_PATH + pictureName));
        MultipartRequest multipartRequest = new MultipartRequest(Utils.BASE_URL + "editprofile/" + appPreferences.getInt(Utils.PROPERTY_USER_ID, -1), new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // TODO Auto-generated method stub
                Log.d("Error: ", error.toString());
                FugaDialog.showErrorDialog(ProfileActivity.this);
            }
        }, new Response.Listener<String>() {
            @Override
            public void onResponse(String jsonResponse) {
                JSONObject response = null;
                try {
                    Log.d("jsonResponse: ", jsonResponse);
                    response = new JSONObject(jsonResponse);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
                try {
                    if (response != null && response.has("statusmessage") && response.getBoolean("statusmessage")) {
                        updateLocalRecord();

                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                FugaDialog.dismiss();
            }

        }, files, params);
        RequestQueue queue = Volley.newRequestQueue(this);
        queue.add(multipartRequest);
Omaomaha answered 31/10, 2015 at 18:11 Comment(0)
W
0

For posterity, I didn't see okhttp mentioned. Related post.

Basically you build up the body using a MultipartBody.Builder, and then post this in a request.

Example in kotlin:

    val body = MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart(
                "file", 
                file.getName(),
                RequestBody.create(MediaType.parse("image/png"), file)
            )
            .addFormDataPart("timestamp", Date().time.toString())
            .build()

    val request = Request.Builder()
            .url(url)
            .post(body)
            .build()

    httpClient.newCall(request).enqueue(object : okhttp3.Callback {
        override fun onFailure(call: Call?, e: IOException?) {
            ...
        }

        override fun onResponse(call: Call?, response: Response?) {
            ...
        }
    })
Winthorpe answered 23/9, 2016 at 21:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.