How to Upload a File With Retrofit - Android Studio Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys and welcome back to a new video in this video i will show you how you can upload a file specifically an image with retrofit however that will be the same with any other type of file you want to upload so very simple app that's all i want to show you we simply have a button which we can click and then we will upload a file to a server i have written a little basic like sample server here in ktor you can get the source code of this in this description and run it if you have intellij however you don't need this to follow through this tutorial like you need this to test if it works but you can also just trust me that it works if you have some other kind of back end that accepts uh some kind of files so i will of course explain how all this works but just to show you a little demo here we have our main folder so build resources main that's the folder where i actually save the file that we upload right now there is no file in there except for the xml file but we want to upload an image file that we get from the assets folder in android and here in the app if we then click upload image go back then we can see we actually have a new static folder images and my image here a little image from me on stage that is what i will upload here you can upload anything you want but just as we'll demo that this works maybe as a little background so you actually understand how it works to upload a file using retrofit or using http requests that usually happens via so-called multi-part requests so a multi-part request is well request that consists of multiple parts a surprise so you can see that here how we actually receive that server side we first of all receive that multi-part request and then we kind of loop over each part of that and there are different types of parts we can have here we can either have a form item or file item there are some more but not relevant for our needs here a form item would be if we would want to actually send some string data along with our file so sometimes you want to also send a file name sometimes you want to maybe also send some kind of json json request also to the server maybe if the user updated their profile and like the profile image is part of that update then you want to basically upload a file but also some kind of data maybe the new user name the new um whatever i don't know any any type of data you want to attach to that file request that would be a form item so if you simply want to attach a string value and then on the other side we have a file item which obviously consists of an actual files of the actual bytes and each part can then have a name that's how we can actually check if this is the part that we think it is so if this is the image part that's how i call it then we simply want to save that image here at this specific given path so that's the server side of things here remember it's a post request and the endpoint is called slash file that's why we need to make the request and send it to however if you of course have a different type of api then this will of course differ let's switch back to android studio and in here i already added some dependencies which you can also find in the source code in github in this video description so we have our compose dependency for yeah just vm models i will have a very very basic example here um nothing special also not following any specific architectural patterns and we of course have retrofit where we which will basically use to make http requests and to also upload the file to our cater server cool if you've done that and added these dependencies we can actually jump into our root folder because what we need to do is we first of all need to add a file that we want to upload so the easiest way to do that is just to create an assets folder in which you can easily add some images of course that could also come from the user selecting a file from their from their phone or so but that's a little bit more difficult if you're dealing with like content yuri's and stuff like that to keep this as simple as possible here for this tutorial i will actually use the assets folder which we need to create so we need to go to project and in our main source set here open this right click and we create a new directory and we call this assets we can already select what it suggests here and then you pick any type of image you have and basically copy this into this assets folder i'll call it image.jpg and if we open this here there you go there's our beautiful image as i said you can pick any type of file you can can also be a text file or whatever you like and the next step then is to actually create our retrofit interface so i will switch back to the android tab and in here i will create a new file called file api select interface and all you want to do all you want to have in here is one single function that is used to upload our image so that will be a suspend function upload image and since that's kind of a special function here since it uploads a file and it doesn't just make a request we need to annotate this with multi-part and that's exactly what i explained that we basically are able to attach multiple different parts to our request and these parts can either be as i said a string value or um just a file that we want to attach in this example we only attach a file but i will also quickly show you how it would um how it would work if you actually want to attach string value as well here for the parameters of this function we need to annotate each parameter with part so that is how we how we tell retrofit and this is one part of our multi-part request and here in this case this would simply be the image that we want to attach and that is of type multi-part body dot part that's the form that we actually need to use here this function doesn't need to return anything um since the api also doesn't return anything keeping this as simple as possible and then in a companion object here i will simply have a global singleton instance of this api so val instance by lazy and here we can simply use our retrofit builder retrofits dot builder set the base url and here you of course need to use the base ul of your api um for me it is http um i guess pretty much my local ip address which is this one you can find this out by either typing ipconfig in your cmd if you're on windows or if you're on mac os you can go to your wi-fi here and go to like settings or so and then it will show you that ip of your local machine where the server is running of course only if you're running your server locally and then we can simply call build and create and we can import crate here and what is the issue here um probably some issues with create let's just specify our file api oh yeah of course because we didn't specify that before but that way it's fine we have our global instance and what i want to do is i want to simply create a very basic repository um file repository or so which will make use of that retrofit instance so that will have a suspend function upload image and this will take the file that we actually want to upload so we first of all will actually need to read that image from our assets folder and actually save it in a file and we will do that in our cache directory on android that each app has and then we will take this and attach it to this function to finally upload it and here we can simply return a trying cache block and to catch actually io exceptions we could print the stack trace and it's also a question if you actually want to return this you could for example return a boolean whether this request was successful or not so here we could return false but in this video i won't do anything with that information we also want to catch http exceptions of the server answers with a non-successful response we can also print this and also return false and in the try block we can use our file api instance the upload image and now we need to actually attach this multi-part body part how do we do that it's actually very simple if you have a file like a file in this format since we can simply say multipart body dot part dot create form data that is the function we want and you can see there are two different overload versions of this on the one hand we have a name and value that would be if you would want to attach a form data in form of like just a string so for example if you would do a normal request that is what would be done so you would have a name how you can actually identify that specific part and you have a value which is for example the file name it could also be some kind of json body or so that the server then deserializes and stuff like that however since we want to attach a file here we will use the second overload which will take a string a file name and a request body first of all the name of this will be image that is how the server will identify that this is actually the image it should save on yeah on its local file system the file name will be file.name and the request body we can simply get that by using an extension function from file that as request body and if you would again just have multiple parameters here for your upload image function that would also take some kind of other other data or so so you would simply attach a string or so then you would simply give this function more parameters also annotate these with part and then also yeah kind of create these with this with this way of doing it after that we can return true and we are good for our file repository as a next step i like to have a little view model nothing special here just create a file view model for example and yeah i will just directly create an instance of our repository in here like this in an actual app you would use dependent injection for that something like dagger health or so and eject an instance of this but i want to keep this as simple as possible here and then we can say function upload image pass the file and here we launch a curtin in view model scope since our function from the repository says pen function we need this and here we can simply say repository dot upload file i upload image and we pass our file that's it that's a function we will call from the ui so that's the last step we actually need to do here in our main activity let's have an instance of our view model using our compose viewmodel initialize function i'm going to create a file view model and then we simply have a box here let's say modifier fill mag size and it will work the same way in xml then it would simply create a button or so and then use an on click listener i i don't do anything else here just in compose so you can also just follow if you're using xml and we can say content alignment center so we have a centered button which we'll put in here cool so we have an on click listener here for this button and we want to give it a little text the text will be uploaded image now the onclicklistener is the interesting part because here we actually want to read our file our image from our assets folder save it in a file instance and basically save it on a file in our cache directory and then we can use that to actually upload it to our server so how will this work we first of all want to create a file like this that first of all needs a parent so where we want to actually save this file that will be our cache directory and we need to do this here in the activity since that requires the contacts usually i wouldn't do this stuff in the activity or in the in the ui layer since that's clearly data related stuff um but again i do this for simplicity in an actual app i would have some separate class that gets access to the application context which you could inject with aggro healed also and then do the stuff there in the data layer but i think for the sake of simplicity simplicity this is totally fine here and the child that will be the file name i will just hard code this here my image.jpg if you would do this dynamically you would also need to kind of find out the extension of the image you the user may be picked or so or whatever you want to upload i want to create this file so file that create new file and we basically now just want to take our file from the assets folder and copy it to this file we just created since that's currently just an empty file there are no bytes in this file so what we can do is we can say file.output stream that we use use is basically just a utility function of kotlin that will automatically close that stream when it finished and in here we can say assets that's how we access our assets folder that open image.jpg that's the name we actually used when we saved our image in the assets folder if you chose something different you of course need to change this and we can say that copy to our output stream so the output stream from our file so that way we just copy our assets file to the output stream of our file so in the end into our file and then all we need to do here is we need to say view model upload image and we pass our file and that should be it for the activity one more little thing we need is internet permission in manifest so users permission internet something people like to forget me included and in here we want users clear text traffic being set to true since i don't have http seo for my api we need to set this to true so the app will kind of support and not break if there is just an http or l and not https however i think that's it if we launch this and i will actually go to my back end and say and delete that image so you can actually see that there is a new image uploaded so there is no more image and here we are this is the new newly launched app if we click upload image and go to our backend can we see it maybe we need to refresh not sure if i actually if it recognized that click now it did and it looks like there is a new folder static images my image and we can open this and there it is so everything is working perfectly fine so again if you want to also try this out simply clone this repository here of the server launch it in intellij that's what you would need to install if you don't have it and then you can also just try this out at home but the general goal of this video was just that you understand how it works to upload a file that you understand multi-part requests because um yeah that's typically the way that is done so that was it for uploading a file with retrofit if you also want to learn how you can download a file with retrofit then let me know that down below using a simple comment and maybe i also do a video about that have an amazing day and rest of the week see you in the next video bye bye you
Info
Channel: Philipp Lackner
Views: 38,167
Rating: undefined out of 5
Keywords: android, tutorial, philip, philipp, filipp, filip, fillip, fillipp, phillipp, phillip, lackener, leckener, leckner, lackner, kotlin, mobile, file, image, upload, retrofit, multipart, request, response, error, api, server, remote, backend
Id: fEYhQOUe0g0
Channel Id: undefined
Length: 16min 32sec (992 seconds)
Published: Sun Jul 24 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.