5

i am trying to upload a image to server from an android phone. this is what i have done so far

  OkHttpClient client = new OkHttpClient();
            MultipartBuilder builder = new MultipartBuilder();


builder.type(MultipartBuilder.FORM).addPart(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), requestPackage.getJsonParam().toString()));
            for (int i = 0; i < requestPackage.getPics().size(); i++) {
                builder.addPart(RequestBody.create(MediaType.parse("image/png"/* + i*/), new File(URI.create(requestPackage.getPics().get(i)))));
            Log.i("image to upload",URI.create(requestPackage.getPics().get(i)).toString());
            }
            requestBody = builder.build();
     Request request = new Request.Builder().url(requestPackage.getUri()).post(requestBody).build();
            try {
                response = client.newCall(request).execute();
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
    //            System.out.println(response.body().string());
                return response.body().string();
            } catch (IOException e) {
                e.printStackTrace();
            }

how do i add names to the different parts.because if there is no name(key) to them then how will server side guy store it?

shreyas
  • 2,166
  • 3
  • 18
  • 30
  • You first have to ask the 'server side guy' what he expects. A 'name? A 'filename' ? A 'file_name'? An 'uploaded_filename'? – greenapps Nov 12 '14 at 13:38
  • lets says for the image part it should be image1,image2... how do i add it in okhttp? – shreyas Nov 12 '14 at 13:40

5 Answers5

14

Get OkHttp 2.1, and use MultipartBuilder.addFormDataPart() which takes the filename as a parameter.

Jesse Wilson
  • 39,078
  • 8
  • 121
  • 128
  • Just wonder why the documentation at https://github.com/square/okhttp/wiki/Recipes does not recommend addFormDataPart? I followed the recipe steps and the server doesn't recognize the request as multipartFile. (Spring fail to convert string to multipartFile). However, addFormDataPart works. Looking at the source code of addFormDataPart, it adds the "filename" in the disposition string. – worawee.s Apr 16 '15 at 09:43
  • It's a gap. Send us a PR, (but confirm that it the example code still works first please). – Jesse Wilson Apr 17 '15 at 02:47
8

The syntax seems to have changed a bit since the previous answers. I'm using OkHttp 3.2.0.

public void upload(String url, File file) throws IOException {
    RequestBody formBody = new MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("file", file.getName(),
            RequestBody.create(MediaType.parse("image/png"), file))
        .addFormDataPart("other_field", "other_field_value")
        .build();
    Request request = new Request.Builder().url(url).post(formBody).build();
    Response response = this.client.newCall(request).execute();
}
Bryant Kou
  • 1,728
  • 1
  • 19
  • 16
0

You can find all in the official document: https://github.com/square/okhttp/wiki/Recipes

Especially you will be interested in folowing piece from Posting a multipart request:

RequestBody requestBody = new MultipartBuilder()
    .type(MultipartBuilder.FORM)
    .addPart(
        Headers.of("Content-Disposition", "form-data; name=\"title\""),
        RequestBody.create(null, "Square Logo"))
    .addPart(
        Headers.of("Content-Disposition", "form-data; name=\"image\""),
        RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
    .build();
greenapps
  • 11,154
  • 2
  • 16
  • 19
0

Here is a complete solution, of how to upload a file using okhttp3. Firstly, add a file picker with a button on click listener to your code like this:

A button to pick file:

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_choose_file:
        showFileChooser();
        break;
    }
}

private String filePath = null;
private File sourceFile;
private static final int FILE_SELECT_CODE = 0;
private void showFileChooser() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("*/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);

    try {
        startActivityForResult(
                Intent.createChooser(intent, "Select a File to Upload"),
                FILE_SELECT_CODE);
    } catch (android.content.ActivityNotFoundException ex) {
        Toast.makeText(this, "Please install a File Manager.",
                Toast.LENGTH_SHORT).show();
    }
}

Then handle onActivityResult like this:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case FILE_SELECT_CODE:
            if (resultCode == RESULT_OK) {
                // Get the Uri of the selected file
                Uri uri = data.getData();

                File   file = new File(getCacheDir(), getFileName(uri));

                int maxBufferSize = 1 * 1024 * 1024;

                try {
                    InputStream inputStream = getContentResolver().openInputStream(uri);
                    Log.e("InputStream Size","Size " + inputStream);
                    int  bytesAvailable = inputStream.available();
                    int bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    final byte[] buffers = new byte[bufferSize];

                    FileOutputStream outputStream = new FileOutputStream(file);
                    int read = 0;
                    while ((read = inputStream.read(buffers)) != -1) {
                        outputStream.write(buffers, 0, read);
                    }
                    Log.e("File Size","Size " + file.length());
                    inputStream.close();
                    outputStream.close();

                    file.getPath();
                    Log.e("File Path","Path " + file.getPath());
                    file.length();
                    Log.e("File Size","Size " + file.length());

                    if(file.length() > 0){

                        sourceFile = file;
                        filePath = sourceFile.getPath();
                    }


                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (OutOfMemoryError e) {
                    e.printStackTrace();
                }



            } else {


            }

            break;
    }
    super.onActivityResult(requestCode, resultCode, data);
}


private String getMimeType(String path) {
    FileNameMap fileNameMap = URLConnection.getFileNameMap();
    String contentTypeFor = fileNameMap.getContentTypeFor(path);
    if (contentTypeFor == null)
    {
        contentTypeFor = "application/octet-stream";
    }
    return contentTypeFor;
}


public String getFileName(Uri uri) {
    String result = null;
    if (uri.getScheme().equals("content")) {
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        try {
            if (cursor != null && cursor.moveToFirst()) {
                result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
            }
        } finally {
            cursor.close();
        }
    }
    if (result == null) {
        result = uri.getPath();
        int cut = result.lastIndexOf('/');
        if (cut != -1) {
            result = result.substring(cut + 1);
        }
    }
    return result;
}

Finally, handle the file upload along with other needed information like this :

  try {

       UpdateInformation("yourEmailAddress", filePath, sourceFile);

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


private void UploadInformation(String email, final String _filePath, final File file) throws IOException {


    runOnUiThread(new Runnable() {
        @Override
        public void run() {


        //show progress bar here

        }
    });


    OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .build();





    String mime = getMimeType(_filePath);


    RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
            .addFormDataPart("file", file.getName(),
                    RequestBody.create(MediaType.parse(mime), file))
            .addFormDataPart("email", email)
            .build();





    okhttp3.Request request = new okhttp3.Request.Builder()
            .url("yourEndPointURL")
            .post(body)
            .addHeader("authorization", "yourEndPointToken")
            .addHeader("content-type", "application/json")
            .build();



    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            call.cancel();


            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                //hide progress bar here

                }
            });

        }

        @Override
        public void onResponse(Call call, okhttp3.Response response) throws IOException {


            try {

                final String myResponse = response.body().string();


                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                //hide progress bar here

                //Cont from here
                //Handle yourEndPoint Response.



                    }
                });


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


        }



    });
}

Note: Don't forget to add this permission to the manifest file.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Oyewo Remi
  • 406
  • 5
  • 8
-1

You can use multipart like below to send multiple values in single request

        HttpPost    httppost = new HttpPost(mPostURL);
        MultipartEntity entity = new MultipartEntity();
        entity.addPart("value", new StringBody("upload", Charset.forName("UTF-8")));
        File myFile = new File(mFilePath);
        FileBody fileBody = new FileBody(filePath);
        entity.addPart("file", fileBody);
        entity.addPart("filename", new StringBody("fileName", Charset.forName("UTF-8")));
        httppost.setEntity(entity);
        HttpClient httpClient = new DefaultHttpClient();
sunil jain
  • 130
  • 2
  • 11