2

I have following code for downloading file from url to sdcard . This code is working fine for small file , but when the file size is large i am getting the downloaded file size 0. Any help would be appreciated.

Java Code

setContentView(R.layout.activity_download_file);
        String exStorageDirectory = Environment.getExternalStorageDirectory()
                .toString();
        File folder = new File(exStorageDirectory, "Folder");
        folder.mkdir();
        File file = new File(folder, "scjp.pdf");
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        downloadFile(
                "http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf",
                file);

    }

    private void downloadFile(String fileUrl, File directory) {
        try {
            FileOutputStream fileOutput = new FileOutputStream(directory);
            URL url = new URL(fileUrl);
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();
            connection.setRequestMethod("GET");
            connection.setDoOutput(true);
            connection.connect();
            InputStream inputStream = connection.getInputStream();
            byte buffer[] = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buffer)) > 0) {

                fileOutput.write(buffer, 0, len);

            }

            fileOutput.close();
            Thread.sleep(10000);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
sonia
  • 405
  • 2
  • 7
  • 23

3 Answers3

2

Have a try with this code.

package com.example.stack;


import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RelativeLayout;

public class MainActivity extends Activity {



    ProgressDialog mProgressDialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         overridePendingTransition(R.anim.enter, R.anim.enter);
        setContentView(R.layout.activity_main);

        // declare the dialog as a member field of your activity


        // instantiate it within the onCreate method
        mProgressDialog = new ProgressDialog(MainActivity.this);
        mProgressDialog.setMessage("A message");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

        // execute this when the downloader must be fired
        DownloadFile downloadFile = new DownloadFile();
        downloadFile.execute("http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf");
    }



    //The AsyncTask will look like this:

    // usually, subclasses of AsyncTask are declared inside the activity class.
    // that way, you can easily modify the UI thread from here
    private class DownloadFile extends AsyncTask<String, Integer, String> {
        @Override
        protected String doInBackground(String... sUrl) {
            try {
                URL url = new URL(sUrl[0]);
                URLConnection connection = url.openConnection();
                connection.connect();
                // this will be useful so that you can show a typical 0-100% progress bar
                int fileLength = connection.getContentLength();

                // download the file
                InputStream input = new BufferedInputStream(url.openStream());
                OutputStream output = new FileOutputStream("/sdcard/output.pdf");

                byte data[] = new byte[1024];
                long total = 0;
                int count;
                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    publishProgress((int) (total * 100 / fileLength));
                    output.write(data, 0, count);
                }

                output.flush();
                output.close();
                input.close();
            } catch (Exception e) {
            }
            return null;
        }

    //The method above (doInBackground) runs always on a background thread. You shouldn't do any UI tasks there. On the other hand, the onProgressUpdate and onPreExecute run on the UI thread, so there you can change the progress bar:

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mProgressDialog.show();
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
            mProgressDialog.setProgress(progress[0]);
        }
    }

}

Add the following permission in you manifest file .

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>

i have tested in mobile too. its worked.

itsrajesh4uguys
  • 4,610
  • 3
  • 20
  • 31
  • downloadFile.execute("http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf"); where this method is defined? – sonia Mar 05 '13 at 10:16
  • that is not a method. that's AsyncTask. with the argument String (thats is your pdf url). .execute is the way of calling AsyncTask – itsrajesh4uguys Mar 05 '13 at 10:21
0

As per the java doc for public int read (byte\[\] buffer, int offset, int length) method it returns

the number of bytes actually read or -1 if the end of the stream has been reached.

So you should check for -1 rather then 0.

Change your while loop from

 while ((len = inputStream.read(buffer)) > 0) {

                fileOutput.write(buffer, 0, len);

            }

to following

while ((len = inputStream.read(buffer)) != -1) {

                fileOutput.write(buffer, 0, len);

            }

And as pointed out in comments you should do this in background thread or AsyncTask...

EDIT1:

Can you put some logs to see the point of error.. like if the input stream is getting opened or not... Also after the call to connect check for the HTTP response code by calling getResponseCode() method if the response code is 200 then only create the file..

Praful Bhatnagar
  • 7,425
  • 2
  • 36
  • 44
0

Try working with this code:

 URL url;

    long startTime = System.currentTimeMillis();

    // Open a connection to that URL.
    URLConnection ucon = null;
    try {
        url = new URL(
                "http://java.net/downloads/jfjug/SCJP%20Sun%20Certified%20Programmer%20for%20Java%206-0071591060.pdf");
        ucon = url.openConnection();
        Log.i("", "image download beginning: " + url);

        ucon.setReadTimeout(TIMEOUT_CONNECTION);
        ucon.setConnectTimeout(TIMEOUT_SOCKET);

        // Define InputStreams to read from the URLConnection.
        // uses 3KB download buffer
        InputStream is = ucon.getInputStream();
        BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
        FileOutputStream outStream = new FileOutputStream(
                "mnt/sdcard/example.pdf");
        byte[] buff = new byte[5 * 1024];


        int len;
        while ((len = inStream.read(buff)) != -1) {
            outStream.write(buff, 0, len);
        }

        outStream.flush();
        outStream.close();
        inStream.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
Sanket Pandya
  • 1,095
  • 7
  • 21