2

How should I implement retrofit into this code to send an image to the server instead of using Volley? I'm a little confused as I'm a bit new to Java/Android. I would like some guidance on how to achieve this using Retrofit as Volley doesnt seem to be working.

I'm basically sending a base64 string of an image to my server along with the image name and a few other things later on. I also need to retrieve the response from my server and display it on my app. Volley seemed to do that easily, not sure about Retrofit.

Thanks in advance

public class MainActivity extends AppCompatActivity {

private ImageButton ImageButton;
private String encoded_string, image_name;
private Bitmap bitmap;
private File file;
private Uri file_uri;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ImageButton = (ImageButton) findViewById(R.id.camera);
    ImageButton.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View view){
            Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            getFileUri();
            i.putExtra(MediaStore.EXTRA_OUTPUT,file_uri);
            startActivityForResult(i,10);
        }
    });
}

private void getFileUri() {
    image_name = "testing123.jpeg";
    file = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), image_name);

    file_uri = Uri.fromFile(file);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if(requestCode == 10 && resultCode == RESULT_OK){
        new Encode_image().execute();
    }
}

private class Encode_image extends AsyncTask<Void,Void,Void> {
   @Override
   protected Void doInBackground(Void... voids){

       bitmap = BitmapFactory.decodeFile(file_uri.getPath());
       ByteArrayOutputStream stream = new ByteArrayOutputStream();
       bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream);

       byte[] array = stream.toByteArray();
       encoded_string = Base64.encodeToString(array,0);
       return null;
   }

   @Override
   protected void onPostExecute(Void aVoid){
       makeRequest();
   }
}

private void makeRequest() {
    final TextView mTextView = (TextView) findViewById(R.id.text);
    RequestQueue requestQueue = Volley.newRequestQueue(this);
    String URL = "http://128.199.77.211/server/connection.php";
    StringRequest request = new StringRequest(Request.Method.POST, URL,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    mTextView.setText(response);
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            mTextView.setText("That didn't work!");
        }
    }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            HashMap<String, String> map = new HashMap<>();
            map.put("encoded_string", encoded_string);
            map.put("image_name", image_name);

            return map;
        }
    };
    requestQueue.add(request);
  }
}
0248881
  • 731
  • 1
  • 4
  • 21

2 Answers2

3

Using Retrofit 2, you need to use either OkHttp’s RequestBody or MultipartBody.Part classes and encapsulate your file into a request body. Let’s have a look at the interface definition for file uploads.

public interface FileUploadService {  
    @Multipart
    @POST("upload")
    Call<ResponseBody> upload(@Part("description") RequestBody description,
                              @Part MultipartBody.Part file);
}

in Java file

private void uploadFile(Uri fileUri) {  
    // create upload service client
    FileUploadService service =
            ServiceGenerator.createService(FileUploadService.class);

    // https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java
    // use the FileUtils to get the actual file by uri
    File file = FileUtils.getFile(this, fileUri);

    // create RequestBody instance from file
    RequestBody requestFile =
            RequestBody.create(MediaType.parse("multipart/form-data"), file);

    // MultipartBody.Part is used to send also the actual file name
    MultipartBody.Part body =
            MultipartBody.Part.createFormData("picture", file.getName(), requestFile);

    // add another part within the multipart request
    String descriptionString = "hello, this is description speaking";
    RequestBody description =
            RequestBody.create(
                    MediaType.parse("multipart/form-data"), descriptionString);

    // finally, execute the request
    Call<ResponseBody> call = service.upload(description, body);
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call,
                               Response<ResponseBody> response) {
            Log.v("Upload", "success");
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            Log.e("Upload error:", t.getMessage());
        }
    });
}
Vishal Patoliya ツ
  • 3,170
  • 4
  • 24
  • 45
1

Create MultipartBody.Part object from your image.

File imageIdCard = new File(image_path);
RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), imageIdCard);
MultipartBody.Part bodyImage = MultipartBody.Part.createFormData("image_id", imageIdCard.getName(), requestFile);

and upload it

@Multipart
@POST("url")
Call<JsonObect> getResponse(@Part MultipartBody.Part image);
Ravi
  • 34,851
  • 21
  • 122
  • 183