Upload an Image to Server via Retrofit 2.0 in an Android App

Creating a HTTP Multipart Request

Ashish Pandey
4 min readOct 30, 2021
Photo by Sigmund on Unsplash

Well, you might be aware of Retrofit, which is a type-safe REST client for Android. And this library provides a powerful framework for authenticating and interacting with APIs and sending network requests with OkHttp.

We can send HTTP requests and receive HTTP responses via the Retrofit library by the regular way of creating a retrofit instance, defining the endpoints inside of an interface using special retrofit annotations (GET, POST, etc.) to encode details about the parameters and request method.

A regular HTTP request sends data to the server in a Request Body, in the format that the content type specifies. Usually, the content type is “application/json” used to send JSON data. But for sending a file to the server, a Multipart request is made with content type generally as “multipart/form-data”. Oh, wait! What did the word “Multipart request” means? Let’s find out!

What is Multipart ?

A HTTP multipart request is a HTTP request that HTTP clients construct to send files and data over to a HTTP Server. It is commonly used by browsers and HTTP clients to upload files to the server.

A multipart message is a list of parts. A part contains headers and a body. The body of the parts may be of any media type, and contain text or binary data. It’s possible for parts to contain a multipart media type.

In the context of HTTP, multipart is most often used with the “multipart/form-data” media type. It is what browsers use to upload files through HTML forms.

A media type (also known as a Multipurpose Internet Mail Extensions or MIME type) is a standard that indicates the nature and format of a document, file, or assortment of bytes.

Coding Process to Send Image to the Server

  • Firstly, you’ve to create a file. For that first you’ve to create provider_paths.xml in res/xml folder and write below code in it.
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external_files"
path="." />
</paths>
  • Then the next step involves declaring </provider> in AndroidManifest.xml as below.
<application>    <provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">

<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
  • Then inside your activity or fragment get the root directory, create a Uri variable named imageUri, set a name for your image with an extension on a string variable like photo.jpg. Create a file to store the image data and also get it’s Uri (A Uniform Resource Identifier is a compact sequence of characters that identifies an abstract or physical resource) into the variable imageUri.
val getRootDirectoryPath = ContextCompat.getExternalFilesDirs(requireContext(), null)[0].absolutePathvar imageUri: Uri? = null
val fileName = "photo.jpg"
val file = File("$getRootDirectoryPath/$fileName")imageUri = FileProvider.getUriForFile(requireContext(),
requireActivity().packageName + ".provider", file)
  • Now, get an image Uri by capturing an image from the Camera app or Gallery app. For reference, you can visit my other blog explaining that process.

In short, you’ll use our earlier declared imageUri variable to get image Uri stored on this variable via the process mentioned in the above-linked blog.

  • Now that you’ve got the image saved in the file with file name photo.jpg, you can call the function below.

You can put this function in your ViewModel maybe along with using any async mechanism like RxJava, Coroutines etc. Here for simplicity I’ve not used or shown like that, but its good to go with a good architecture approach.

In the code above, I’ve created three Part variables for Multipart Request for demonstration purposes only! But you can create any number as required in the API.

The body of the two Parts, i.e, userIdRequestBody and descriptionRequestBody are of media type text/plain and that of Part filePart is image/*.

  • Finally, in your actual API interface, you can put the code as written below.

Here, you’ve to annotate the photo upload Retrofit endpoint, i.e, “user/photo" with @Multipart to make it a Multipart Request with all its Part parameters with @Part .

Finally your image will be uploaded onto the Server via this Retrofit call

If you are keen and enthusiastic to know more about Android Development, please do follow!

Photo by Denny Müller on Unsplash

--

--

Ashish Pandey

An enthusiastic Android Developer sharing stuff that pops up inside my right brain out of processed stuff from my left brain