Search code examples
javafile-uploadretrofitretrofit2

Not able to upload image to server with retrofit


I am currently working on a personal project in which I want to upload a profile pic to my server. I can easily put an image to a server with postman by sending it in form-data but when I do the same with retrofit it does not work, and sometimes it creates a 1kb file which shows an error when opening.

What currently I am doing is,

 Uri uri = data.getData();
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                profileImage.setImageBitmap(bitmap);


        
                File file = new File(uri.getPath());
                RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"),file);
                MultipartBody.Part body = MultipartBody.Part.createFormData("Profile", "bcs.jpeg", reqFile);
                authViewModel.setNewProfilePic(layout,email,body);

and code for setNewProfilePic is,

public void setNewProfilePic(RelativeLayout relativeLayout, String email,MultipartBody.Part part) {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
        api = new Retrofit.Builder().baseUrl(Constants.URL_API).client(client).build().create(SpendistryAPI.class);
        retrofit2.Call<okhttp3.ResponseBody> req = api.setNewProfilePic(email,part);
        req.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                // Do Something
                if (!response.isSuccessful()) {
                    Toast.makeText(application, "notWorking: " + response.code(), Toast.LENGTH_SHORT).show();
                    return;
                }
                try {
                    Toast.makeText(application, response.body().string(), Toast.LENGTH_SHORT).show();
                } catch (Exception e) {
                    Toast.makeText(application, "catch", Toast.LENGTH_SHORT).show();
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                t.printStackTrace();
            }
        });

if i provie file to RequestBody.create like,

File file = new File(uri.getPath());
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"),file);

code of setting new profile pic does not get executed and if I pass only URI.getPath() in .create() method id creates image file on the server with 1kb which can not be opened.

please help me with this situation, Thanks in advance!!


Solution

  • What I think is that you might not have given the read external storage permission, uri.getPath() will not work, you have to find a real path from uri for that you can use this code

    private String getRealPathFromURI(Uri contentUri) {
            String[] proj = {MediaStore.Images.Media.DATA};
            CursorLoader loader = new CursorLoader(this, contentUri, proj, null, null, null);
            Cursor cursor = loader.loadInBackground();
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            String result = cursor.getString(column_index);
            cursor.close();
            return result;
        }
    

    Now, pass this string to file otherwise code is perfect!

    FILE file = new file(getRealPathFromURI(uri));