37

I have to download a file and I'm using this code, which is basically an AsyncTask that is meant to update a progress bar. But, since I don't know what's the file size I've been having to use the spinner progress bar. So, how can I get the file size before start downloading it so that I can use a normal progress bar?

Cristian
  • 198,401
  • 62
  • 356
  • 264
  • Note that you should call `urlConnection.connect()` before attempting to access the `Content-Length` header. Not doing so might work, but not under all possible circumstances. – Felix Jun 06 '10 at 15:47
  • Didn't know that... it worked that way for me, but thanks for your advice. I'm going to edit the answer. – Cristian Jun 06 '10 at 16:00

2 Answers2

76

you can get a header called Content-Length form the HTTP Response object that you get, this will give you the length of the file. you should note though, that some servers don't return that information, and the only way to know the actual size is to read everything from the response.

Example:

URL url = new URL("http://server.com/file.mp3");
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
int file_size = urlConnection.getContentLength();
Cristian
  • 198,401
  • 62
  • 356
  • 264
reflog
  • 7,587
  • 1
  • 42
  • 47
  • this will work on most cases, but if the file is too large, it won't work. see my post below for a solution that always works: http://stackoverflow.com/a/12271781/878126 – android developer Sep 17 '13 at 12:18
  • 1
    You should use getContentLengthLong() instead of getContentLength() for Android 7 and above. Below that prefer using Long.parseLong(urlConnection.getHeaderField("content-length")) – Sandeep Aug 10 '17 at 13:48
19

you can usually use getContentLength , but the best thing is it get the length by yourself (since it can bypass integer's max value) .

just parse the content-length header value by yourself . better parse it as long .

example:

final URL uri=new URL(...);
URLConnection ucon;
try
  {
  ucon=uri.openConnection();
  ucon.connect();
  final String contentLengthStr=ucon.getHeaderField("content-length");
  //...
  }
catch(final IOException e1)
  {
  }

do note that i can be any string , so use try catch , and if it's -1, empty , or null , it means that you can't know the size of the file since the server doesn't allow it.

EDIT: Here's a more updated code, using Kotlin:

@JvmStatic
@WorkerThread
fun getFileSizeOfUrl(url: String): Long {
    var urlConnection: URLConnection? = null
    try {
        val uri = URL(url)
        urlConnection = uri.openConnection()
        urlConnection!!.connect()
        if (VERSION.SDK_INT >= Build.VERSION_CODES.N)
            return urlConnection.contentLengthLong
        val contentLengthStr = urlConnection.getHeaderField("content-length")
        return if (contentLengthStr.isNullOrEmpty()) -1L else contentLengthStr.toLong()
    } catch (ignored: Exception) {
    } finally {
        if (urlConnection is HttpURLConnection)
            urlConnection.disconnect()
    }
    return -1L
}
android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • 1
    Java's int primitive is a 32-bit signed integer; you probably won't surpass the max value with a Content-Type header – mjama Mar 29 '13 at 05:07
  • 5
    actually you can, it's about 2GB . – android developer Mar 29 '13 at 06:48
  • so what to do at server side to make it allow..? – Kalpesh Lakhani Mar 01 '14 at 09:01
  • @KalpeshLakhani I don't know about the server side. only the client side. The question here is about Android, which functions in this case as the client side. sorry. maybe those could help: http://stackoverflow.com/questions/6918016/how-to-configure-httpserver-to-use-content-length-and-not-transfer-encoding-chu http://stackoverflow.com/questions/14903404/why-is-the-content-length-header-omitted-from-server-response-when-using-httpcli – android developer Mar 01 '14 at 09:03
  • ohk thanks a lot for reply..is there any other way to get size(in kb) of downloaded data from server ? method is post in my case. i m getting text data in xml format. thanks a lot for your valuable time buddy..:) – Kalpesh Lakhani Mar 01 '14 at 09:19
  • @KalpeshLakhani I'm not sure what you are asking. Are you asking about the amount of data the app has downloaded so far of a file-url? if so, that's something that is a part of the "algorithm" to download a file - your loop includes reading from the inputStream, and you increase a counter of the bytes to know how many bytes were read so far. the "read" method of inputStream returns the number of bytes read: http://developer.android.com/reference/java/io/InputStream.html#read(byte[]) . here's a sample usage : http://stackoverflow.com/a/2509258/878126 – android developer Mar 01 '14 at 09:25
  • Sorry for confusion..Actually i m calling one web service which will return me list of contacts in xml format..like..kalpeshAndroid... so what i want is to found the size of this xml data which returns by Wservice. (i want size in kb). for example data size is 500kb etc – Kalpesh Lakhani Mar 01 '14 at 09:31
  • @KalpeshLakhani ok, what i've written is in bytes, so you just need to divide the result by 1024 in order to get it in KilloBytes (kb=KiloBits, KB=KiloBytes) – android developer Mar 01 '14 at 09:49