Upload a file by using retrofit in android

Sharing is caring!

In this tutorial, we will learn how to upload a file on the server by using Retrofit.  Retrofit is the most popular for networking API call. It is very simple and cleaner way API call in the Android application. Retrofit used OkHttp request call which is extended and customized of Http request.

Android developers love this because it is pretty simple and easy to integrate into an android application.  Retrofit is not only simple to integrate but also provide many features for handling multiple requests like Dispatcher, caching, and easy to handle the error.  Great 🙂

Retrofit works very seamlessly with RxJava. RxAndroid provides the Android Scheduler for scheduling the main thread switch between the threads easily. Now a day Reactive is getting popular in android application development. Android developers love this because it gives a really good response to become your app reactive.

Please check this post to understand that how to use API call by using retrofit in Kotlin? Please check these post of reactive nature to better understand. RxJava2 in Android Part-1, RxJava in Android part-2 and Understanding Java 8 Stream and RxJava2 Observable in Android.

Ok, Let’s see how to upload an image file to the server by using retrofit? First of all, we need to add the retrofit dependency file in your app grade file.

// Retrofit + GSON + Interceptor retrofit_version = '2.2.0'
    compile "com.squareup.retrofit2:retrofit:$retrofit_version"
    compile "com.squareup.retrofit2:adapter-rxjava2:$retrofit_version"
    compile "com.squareup.retrofit2:converter-gson:$retrofit_version"
    compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'

Now you need to create an input model class for image upload and for the retrofit response we need to create image output model class. Why is POJO class for the response which is given by server? The server gives the response in the format of JSON. But Retrofit internally used GSON Library to convert JSON format to plain Java object class.

public class ImageUploadInputModel {

    @SerializedName("image")
    @Expose
    private File image;

    @SerializedName("user_id")
    @Expose
    private Integer userID;

    public File getImage() {
        return image;
    }

    public void setImage(File image) {
        this.image = image;
    }

    public Integer getUserID() {
        return userID;
    }

    public void setUserID(Integer userID) {
        this.userID = userID;
    }
}

Here is the get response model.

public class ImageUploadOutputModel {

    @SerializedName("response")
    @Expose
    private Response response;
    @SerializedName("error")
    @Expose
    private String error;
    @SerializedName("status_code")
    @Expose
    private Integer statusCode;

    public Response getResponse() {
        return response;
    }

    public void setResponse(Response response) {
        this.response = response;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    public Integer getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(Integer statusCode) {
        this.statusCode = statusCode;
    }

    public class Response {

        @SerializedName("image")
        @Expose
        private String image;
        @SerializedName("message")
        @Expose
        private String message;

        public String getImage() {
            return image;
        }

        public void setImage(String image) {
            this.image = image;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

    }
}

Now you need to create APIClient class to get an instance of Retrofit.

public class ApiClient {

    private static ApiClient instance;
    private APIService apiService;
    Context context;
    Retrofit retrofit;

    String TAG = ApiClient.class.getSimpleName();

    public static ApiClient getInstance(Context context) {
        if (instance == null) {
            instance = new ApiClient(context);
        }
        return instance;
    }

    private ApiClient(Context context) {
        this.context = context;

        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
                .create();

        OkHttpClient client = new OkHttpClient();

        retrofit = new Retrofit.Builder()
                .baseUrl(Constants.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(client)
                .build();
        apiService = getAPIServiceEndPoint();
    }

    public APIService getAPIServiceEndPoint() {
        if (apiService == null) {
            apiService = retrofit.create(APIService.class);
        }

        return apiService;
    }
}

Here is the interface API service to execute the network call. For image upload, Retrofit is using multipart concept.

   public interface APIService {

        @Multipart
        @POST("image/")
        Call<ImageUploadOutputModel> uploadImage(@Part("user_id") RequestBody userId, @Part("image\"; filename=\"image.png\" ") RequestBody file);

    }

Let’s create a method to upload an image by retrofit.

  public void uploadImage( final ImageUploadInputModel imageUploadInputModel) {

        RequestBody userId = RequestBody.create(MediaType.parse("text/plain"), imageUploadInputModel.getUserID().toString());
        RequestBody image = RequestBody.create(MediaType.parse("multipart/form-data"), imageUploadInputModel.getImage());

        final Call<ImageUploadOutputModel> response = apiService.uploadImage(userId, image);

        response.enqueue(new Callback<ImageUploadOutputModel>() {
            @Override
            public void onResponse(Call<ImageUploadOutputModel> call, Response<ImageUploadOutputModel> response) {
                if (response.body() != null && response.body().getStatusCode() == 200) {
                    Log.v("", "success " + response.code()+ "body: "+response.body().toString());
                    // send call back

                } else {
                    if (response != null && response.body() != null && response.body().getError() != null)
                        Toast.makeText(context, response.body().getError().toString(), Toast.LENGTH_SHORT).show();
                      // Handle error here
                }
            }

            @Override
            public void onFailure(Call<ImageUploadOutputModel> call, Throwable t) {
                if (t instanceof IOException) {
                    Log.v("", "Network Error");
                }
            }

        });
    }

Ok, Great 🙂 we have done well so for then good to go for upload. Now let’s call to image upload method.

@OnClick(R.id.uplaod)
    public void uploadClick(){
            ImageUploadInputModel imageUploadInputModel = new ImageUploadInputModel();
            imageUploadInputModel.setUserID(1);
            File file = new File(mFile);
            imageUploadInputModel.setImage(file);
            ApiClient.getInstance(this).uploadImage(imageUploadInputModel);
    }

Wrapping Up: As we practiced that retrofit is very simple and easy to integrate into Android for building awesome Android apps. It will work seamlessly with all design pattern in android. Here is the tutorial to learn how to use Retrofit in MVP design pattern with Kotlin?

Please do subscribe your email to get every newsletter from this blog and if you feel that this post helps you then do not forget to share and comment below.

Happy Coding 🙂

3.5 2 votes
Article Rating
Upload a file by using retrofit in android
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Nayan

can i download video in background using retrofit ?

Scroll to top
1
0
Would love your thoughts, please comment.x
()
x