1

today I'm trying to implement a file download, with a notification about how many bytes are downloaded already (Like "1Mb of 150Mb downloaded"). However, I'm stuck in some maths.

class DescarregarFitxer extends AsyncTask<String,String,String>{
    final String rutaDesti;
    final String urlOrigen;
    URLConnection urlConnect;
    View v;
    byte[] buffer = new byte[8 * 1024];

    public DescarregarFitxer(String rutaDesti, String urlOrigen, View v){
        this.rutaDesti = rutaDesti;
        this.urlOrigen = urlOrigen;
        this.v = v;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

    }

    protected String doInBackground(String... params) {
        try{
            int size = 0;
            int counter = 0;
            URL url = new URL(urlOrigen);
            urlConnect = url.openConnection();
            size = urlConnect.getContentLength();
            productView.this.callBackDownload(v, "{'action':'start','size':'"+size+"'}");
            InputStream input = urlConnect.getInputStream();
            try {
                OutputStream output = new FileOutputStream(rutaDesti);
                try {
                    int bytesRead;
                    while ((bytesRead = input.read(buffer)) != -1) {
                        output.write(buffer, 0, bytesRead);
                        counter+=buffer.length;
                        productView.this.callBackDownload(v, "{'action':'update','size':'"+size+"','counter':'"+counter+"'}");
                    }
                } finally {
                    output.close();
                }
            } finally {
                input.close();
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        productView.this.callBackDownload(v, "{'action':'done'}");
    }
}

As you can see in the above code, several things must be noted:

  • As soon as download starts, I get the lenght of the file to be downloaded.
  • Every loop on the while, I've a callback to update a TextView with the size downloaded.

I've everything I need, but I am not sure what do now.

Example:

  • File size: 9383138 bytes
  • Every Loop: 8192 bytes

However, I did this in the callback:

Log.d("debugging","we downloaded: "+counter+" of "+size);

And when it ends, it says:

we downloaded : 26206208 of 9383138

As you can see, some of my calculations are wrong. Maybe I'm doing maths with different kind of units.

Can you help me?

Thanks!!

Reinherd
  • 5,476
  • 7
  • 51
  • 88

4 Answers4

1

Try adding up bytesRead instead of buffer.length.

Gil Moshayof
  • 16,633
  • 4
  • 47
  • 58
1
counter+=buffer.length;

That's not the amount of bytes downloaded

counter+=bytesRead;

Is. Just like you write bytesRead bytes to your file

njzk2
  • 38,969
  • 7
  • 69
  • 107
  • You both were right. Now it is working correctly. However Gil Moshayof gave the answer 30 seconds earlier! – Reinherd Oct 08 '13 at 09:24
1

For a very large download, you should not use an AsynTask. They have not been designed for this : https://stackoverflow.com/a/13082084/693752

You got 2 solutions :

Community
  • 1
  • 1
Snicolas
  • 37,840
  • 15
  • 114
  • 173
  • That question states some issues which I already control (when activity is destroyed, I cancel the AsyncTask). For now I'll keep using it if it doesn't make any troubles. As soon as I've any, I will remember this and will go for a better approach. Thanks for the advice!! – Reinherd Oct 08 '13 at 09:32
0

use bytesRead to be increament with counter

counter += bytesRead;
Riskhan
  • 4,434
  • 12
  • 50
  • 76