David
David

Reputation: 109

How to download zip file with java code in android correctly?

I try to download a zip file to android and then extract the zip file. I debug my code and there is a funny problem: The downloaded zip file is a bit larger than origin file. And the downloaded zip file can't be unziped by winrar. It is said that the downloaded file is ended with error. (The zip file on my website is OK. I try to download with IE. It works fine.) Following is my code:

public void download(final String url, final String savePath, final String saveName) {
    new Thread(new Runnable() {
        public void run() {
            try {
                sendMessage(FILE_DOWNLOAD_CONNECT);
                URL sourceUrl = new URL(url);
                URLConnection conn = sourceUrl.openConnection();
                conn.connect();
                InputStream inputStream = conn.getInputStream();

                int fileSize = conn.getContentLength();

                File savefilepath = new File(savePath);
                if (!savefilepath.exists()) {
                    savefilepath.mkdirs();
                }
                File savefile = new File(savePath+saveName);
                if (savefile.exists()) {
                    savefile.delete();
                }
                savefile.createNewFile();

                FileOutputStream outputStream = new FileOutputStream(
                    savePath+saveName, true);

                byte[] buffer = new byte[1024];
                int readCount = 0;
                int readNum = 0;
                int prevPercent = 0;
                while (readCount < fileSize && readNum != -1) {
                    readNum = inputStream.read(buffer);
                    if (readNum > -1) {
                        outputStream.write(buffer);

                        readCount = readCount + readNum;

                        int percent = (int) (readCount * 100 / fileSize);
                        if (percent > prevPercent) {
                            sendMessage(FILE_DOWNLOAD_UPDATE, percent,
                                readCount);

                            prevPercent = percent;
                        }
                    }
                }
                outputStream.flush();
                outputStream.close();
                inputStream.close();
                //Thread.sleep(50);
                sendMessage(FILE_DOWNLOAD_COMPLETE, savePath);

            } catch (Exception e) {
                sendMessage(FILE_DOWNLOAD_ERROR, e);
            }
        }
    }).start();
}

Anybody know this issue?

Upvotes: 2

Views: 5107

Answers (2)

Sandeep
Sandeep

Reputation: 2593

public class Download extends Activity {
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;

private ProgressDialog mProgressDialog;
    public String app_name ;
    public String urlpath ;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);



app_name="test.rar";        
    urlpath = "https://www.abc.com/download/"+ app_name;
    if (android.os.Environment.getExternalStorageState().equals
            (android.os.Environment.MEDIA_MOUNTED))
    {        
        startDownload();
    }

    else
    {
         Toast.makeText(getApplicationContext(), "SD Card not found,Insert SD card and try again", Toast.LENGTH_SHORT).show();
    }

}

private void startDownload() {

    new DownloadFileAsync().execute(urlpath);
}
@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
        case DIALOG_DOWNLOAD_PROGRESS:
            mProgressDialog = new ProgressDialog(this);
            mProgressDialog.setMessage("Downloading Updates..");
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            mProgressDialog.setCancelable(false);
            mProgressDialog.setIndeterminate(false);
            mProgressDialog.setMax(100);
            mProgressDialog.show();
            return mProgressDialog;
        default:
            return null;
    }
}
class DownloadFileAsync extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        showDialog(DIALOG_DOWNLOAD_PROGRESS);
    }

    @Override
    protected String doInBackground(String... aurl) {


        try {


            URL url = new URL(urlpath.toString()); // Your given URL.

            HttpURLConnection c = (HttpURLConnection) url.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect(); // Connection Complete here.!


            int lenghtOfFile = c.getContentLength();


            Log.d("Downloading Updates", "Lenght of file: " + lenghtOfFile);

            String PATH = Environment.getExternalStorageDirectory() + "/download/";

            File file = new File(PATH); // PATH = /mnt/sdcard/download/

            if (!file.exists()) {
                file.mkdirs();
            }
            File outputFile = new File(file, app_name);           
            FileOutputStream fos = new FileOutputStream(outputFile);



            InputStream is = c.getInputStream(); /

            byte[] buffer = new byte[1024];
            int len1 = 0;
            long total = 0;
            while ((len1 = is.read(buffer)) != -1) {
                total += len1;
                publishProgress(""+(int)((total*100)/lenghtOfFile));

                fos.write(buffer, 0, len1); // Write In FileOutputStream.
            }
            fos.flush();
            fos.close();
            is.close();
        } catch (Exception e) {}
        return null;

    }
    protected void onProgressUpdate(String... progress) {
         Log.d("Downloading Updates",progress[0]);
         mProgressDialog.setProgress(Integer.parseInt(progress[0]));
    }

    @Override
    protected void onPostExecute(String unused) {
        dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
        finish();
    }
}
}

Upvotes: 2

Ted Hopp
Ted Hopp

Reputation: 234795

When you read into the buffer, you are writing the entire buffer to the output stream:

outputStream.write(buffer);

You should only write the part of the buffer that was filled:

outputStream.write(buffer, 0, readNum);

Particularly with network downloads, there is no guarantee that a call to inputStream.read(buffer) will fill the buffer (even if there is more than 1024 bytes to go in the file).

Upvotes: 5

Related Questions