1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.googlecode.android_scripting; 18 19 import android.app.ProgressDialog; 20 import android.content.Context; 21 import android.content.DialogInterface; 22 import android.os.AsyncTask; 23 24 25 import com.googlecode.android_scripting.exception.Sl4aException; 26 27 import java.io.File; 28 import java.io.FileNotFoundException; 29 import java.io.FileOutputStream; 30 import java.io.IOException; 31 import java.io.OutputStream; 32 import java.net.MalformedURLException; 33 import java.net.URL; 34 import java.net.URLConnection; 35 36 /** 37 * AsyncTask for extracting ZIP files. 38 * 39 */ 40 public class UrlDownloaderTask extends AsyncTask<Void, Integer, Long> { 41 42 private final URL mUrl; 43 private final File mFile; 44 private final ProgressDialog mDialog; 45 46 private Throwable mException; 47 private OutputStream mProgressReportingOutputStream; 48 49 private final class ProgressReportingOutputStream extends FileOutputStream { 50 private int mProgress = 0; 51 ProgressReportingOutputStream(File f)52 private ProgressReportingOutputStream(File f) throws FileNotFoundException { 53 super(f); 54 } 55 56 @Override write(byte[] buffer, int offset, int count)57 public void write(byte[] buffer, int offset, int count) throws IOException { 58 super.write(buffer, offset, count); 59 mProgress += count; 60 publishProgress(mProgress); 61 } 62 } 63 UrlDownloaderTask(String url, String out, Context context)64 public UrlDownloaderTask(String url, String out, Context context) throws MalformedURLException { 65 super(); 66 if (context != null) { 67 mDialog = new ProgressDialog(context); 68 } else { 69 mDialog = null; 70 } 71 mUrl = new URL(url); 72 String fileName = new File(mUrl.getFile()).getName(); 73 mFile = new File(out, fileName); 74 } 75 76 @Override onPreExecute()77 protected void onPreExecute() { 78 Log.v("Downloading " + mUrl); 79 if (mDialog != null) { 80 mDialog.setTitle("Downloading"); 81 mDialog.setMessage(mFile.getName()); 82 // mDialog.setIndeterminate(true); 83 mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 84 mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { 85 @Override 86 public void onCancel(DialogInterface dialog) { 87 cancel(true); 88 } 89 }); 90 mDialog.show(); 91 } 92 } 93 94 @Override doInBackground(Void... params)95 protected Long doInBackground(Void... params) { 96 try { 97 return download(); 98 } catch (Exception e) { 99 if (mFile.exists()) { 100 // Clean up bad downloads. 101 mFile.delete(); 102 } 103 mException = e; 104 return null; 105 } 106 } 107 108 @Override onProgressUpdate(Integer... progress)109 protected void onProgressUpdate(Integer... progress) { 110 if (mDialog == null) { 111 return; 112 } 113 if (progress.length > 1) { 114 int contentLength = progress[1]; 115 if (contentLength == -1) { 116 mDialog.setIndeterminate(true); 117 } else { 118 mDialog.setMax(contentLength); 119 } 120 } else { 121 mDialog.setProgress(progress[0].intValue()); 122 } 123 } 124 125 @Override onPostExecute(Long result)126 protected void onPostExecute(Long result) { 127 if (mDialog != null && mDialog.isShowing()) { 128 mDialog.dismiss(); 129 } 130 if (isCancelled()) { 131 return; 132 } 133 if (mException != null) { 134 Log.e("Download failed.", mException); 135 } 136 } 137 138 @Override onCancelled()139 protected void onCancelled() { 140 if (mDialog != null) { 141 mDialog.setTitle("Download cancelled."); 142 } 143 } 144 download()145 private long download() throws Exception { 146 URLConnection connection = null; 147 try { 148 connection = mUrl.openConnection(); 149 } catch (IOException e) { 150 throw new Sl4aException("Cannot open URL: " + mUrl, e); 151 } 152 153 int contentLength = connection.getContentLength(); 154 155 if (mFile.exists() && contentLength == mFile.length()) { 156 Log.v("Output file already exists. Skipping download."); 157 return 0l; 158 } 159 160 try { 161 mProgressReportingOutputStream = new ProgressReportingOutputStream(mFile); 162 } catch (FileNotFoundException e) { 163 throw new Sl4aException(e); 164 } 165 166 publishProgress(0, contentLength); 167 168 int bytesCopied = IoUtils.copy(connection.getInputStream(), mProgressReportingOutputStream); 169 if (bytesCopied != contentLength && contentLength != -1) { 170 throw new IOException("Download incomplete: " + bytesCopied + " != " + contentLength); 171 } 172 mProgressReportingOutputStream.close(); 173 Log.v("Download completed successfully."); 174 return bytesCopied; 175 } 176 } 177