39 * |
39 * |
40 * a typical call to start the task would be new DownloadAsyncTask().execute(getExternalStorage(), "www.hedgewars.org/data.zip"); |
40 * a typical call to start the task would be new DownloadAsyncTask().execute(getExternalStorage(), "www.hedgewars.org/data.zip"); |
41 * @author Xeli |
41 * @author Xeli |
42 * |
42 * |
43 */ |
43 */ |
44 public class DownloadAsyncTask extends AsyncTask<DownloadPackage, Object, Long> { |
44 public class DownloadAsyncTask extends AsyncTask<DownloadPackage, Object, Integer> { |
45 |
45 |
46 //private final static String URL_WITHOUT_SUFFIX = "http://www.xelification.com/tmp/firebutton."; |
46 //private final static String URL_WITHOUT_SUFFIX = "http://www.xelification.com/tmp/firebutton."; |
47 private final static String URL_ZIP_SUFFIX = ".zip"; |
47 private final static String URL_ZIP_SUFFIX = ".zip"; |
48 private final static String URL_HASH_SUFFIX = ".hash"; |
48 private final static String URL_HASH_SUFFIX = ".hash"; |
49 |
49 |
|
50 public static final int EXIT_SUCCESS = 0; |
|
51 public static final int EXIT_URLFAIL = 1; |
|
52 public static final int EXIT_CONNERROR = 2; |
|
53 public static final int EXIT_FNF = 3; |
|
54 public static final int EXIT_MD5 = 4; |
|
55 public static final int EXIT_CANCELLED = 5; |
|
56 |
50 private DownloadTask task; |
57 private DownloadTask task; |
51 private long lastUpdateMillis = 0; |
58 private long lastUpdateMillis = 0; |
52 |
59 |
53 public DownloadAsyncTask(DownloadTask _task){ |
60 public DownloadAsyncTask(DownloadTask _task){ |
54 task = _task; |
61 task = _task; |
56 |
63 |
57 /** |
64 /** |
58 * |
65 * |
59 * @param params - A {@link}DownloadTask which gives information about where to download from and store the files to |
66 * @param params - A {@link}DownloadTask which gives information about where to download from and store the files to |
60 */ |
67 */ |
61 protected Long doInBackground(DownloadPackage...packages) { |
68 protected Integer doInBackground(DownloadPackage...packages) { |
62 DownloadPackage pack = packages[0];//just use one task per execute call for now |
69 DownloadPackage pack = packages[0];//just use one task per execute call for now |
63 |
70 |
64 HttpURLConnection conn = null; |
71 HttpURLConnection conn = null; |
65 MessageDigest digester = null; |
72 MessageDigest digester = null; |
66 String rootZipDest = pack.getPathToStore(); |
73 String rootZipDest = pack.getPathToStore(); |
67 |
74 |
68 File rootDest = new File(rootZipDest);//TODO check for nullpointer, it hints to the absence of an sdcard |
75 File rootDest = new File(rootZipDest);//TODO check for nullpointer, it hints to the absence of an sdcard |
71 try { |
78 try { |
72 URL url = new URL(pack.getURL() + URL_ZIP_SUFFIX); |
79 URL url = new URL(pack.getURL() + URL_ZIP_SUFFIX); |
73 conn = (HttpURLConnection)url.openConnection(); |
80 conn = (HttpURLConnection)url.openConnection(); |
74 } catch (IOException e) { |
81 } catch (IOException e) { |
75 e.printStackTrace(); |
82 e.printStackTrace(); |
76 return -1l; |
83 return EXIT_URLFAIL; |
77 } |
84 } |
78 |
85 |
79 String contentType = conn.getContentType(); |
86 String contentType = conn.getContentType(); |
80 |
87 |
81 if(contentType == null || contentType.contains("zip")){ //Seeing as we provide the url if the contentType is unknown lets assume zips |
88 if(contentType == null || contentType.contains("zip")){ //Seeing as we provide the url if the contentType is unknown lets assume zips |
82 int bytesDecompressed = 0; |
89 int bytesDecompressed = 0; |
83 ZipEntry entry = null; |
90 ZipEntry entry = null; |
84 ZipInputStream input = null; |
91 ZipInputStream input = null; |
|
92 FileOutputStream output = null; |
85 int kbytesToProcess = conn.getContentLength()/1024; |
93 int kbytesToProcess = conn.getContentLength()/1024; |
86 |
94 |
87 byte[] buffer = new byte[1024]; |
95 byte[] buffer = new byte[1024]; |
88 task.start(kbytesToProcess); |
96 task.start(kbytesToProcess); |
89 |
97 |
98 input = new ZipInputStream(conn.getInputStream()); |
106 input = new ZipInputStream(conn.getInputStream()); |
99 entry = input.getNextEntry(); |
107 entry = input.getNextEntry(); |
100 }catch(IOException e){ |
108 }catch(IOException e){ |
101 e.printStackTrace(); |
109 e.printStackTrace(); |
102 if(conn != null) conn.disconnect(); |
110 if(conn != null) conn.disconnect(); |
103 return -2l; |
111 return EXIT_CONNERROR; |
104 } |
112 } |
105 |
113 |
|
114 |
|
115 |
106 while(entry != null){ |
116 while(entry != null){ |
|
117 |
107 if(isCancelled()) break; |
118 if(isCancelled()) break; |
108 |
119 |
109 String fileName = entry.getName(); |
120 try { |
110 File f = new File(rootZipDest + fileName); |
121 String fileName = entry.getName(); |
111 bytesDecompressed += entry.getCompressedSize(); |
122 File f = new File(rootZipDest + fileName); |
112 |
123 bytesDecompressed += entry.getCompressedSize(); |
113 if(entry.isDirectory()){ |
124 |
114 f.mkdir(); |
125 if(entry.isDirectory()){ |
115 }else{ |
126 f.mkdir(); |
116 if(f.exists()){ |
127 }else{ |
117 f.delete(); |
128 if(f.exists()){ |
118 } |
129 f.delete(); |
119 |
130 } |
120 FileOutputStream output = null; |
|
121 try { |
|
122 f.createNewFile(); |
131 f.createNewFile(); |
123 output = new FileOutputStream(f); |
132 output = new FileOutputStream(f); |
124 |
133 |
125 int count = 0; |
134 int count = 0; |
126 while((count = input.read(buffer)) != -1){ |
135 while((count = input.read(buffer)) != -1){ |
131 publishProgress(bytesDecompressed, kbytesToProcess, fileName); |
140 publishProgress(bytesDecompressed, kbytesToProcess, fileName); |
132 } |
141 } |
133 } |
142 } |
134 output.flush(); |
143 output.flush(); |
135 input.closeEntry(); |
144 input.closeEntry(); |
136 } catch (FileNotFoundException e) { |
145 }//if isDir |
137 e.printStackTrace(); |
|
138 if(conn != null) conn.disconnect(); |
|
139 return -3l; |
|
140 } catch (IOException e) { |
|
141 e.printStackTrace(); |
|
142 if(conn != null) conn.disconnect(); |
|
143 return -4l; |
|
144 }finally{ |
|
145 try { |
|
146 if( output != null) output.close(); |
|
147 } catch (IOException e) {} |
|
148 } |
|
149 } |
|
150 try{ |
|
151 entry = input.getNextEntry(); |
146 entry = input.getNextEntry(); |
152 }catch(IOException e){ |
147 } catch (FileNotFoundException e) { |
153 e.printStackTrace(); |
148 e.printStackTrace(); |
154 if(conn != null) conn.disconnect(); |
149 if(conn != null) conn.disconnect(); |
155 return -1l; |
150 return EXIT_FNF; |
|
151 } catch (IOException e) { |
|
152 e.printStackTrace(); |
|
153 if(conn != null) conn.disconnect(); |
|
154 return EXIT_CONNERROR; |
|
155 }finally{ |
|
156 try { |
|
157 if( output != null) output.close(); |
|
158 |
|
159 } catch (IOException e) {} |
156 } |
160 } |
157 }//end while(entry != null) |
161 }//end while(entry != null) |
158 |
162 if( input != null) |
159 try { |
163 try { |
160 input.close(); |
164 input.close(); |
161 } catch (IOException e) {} |
165 } catch (IOException e) {} |
162 }//end if contentType == "zip" |
166 }//end if contentType == "zip" |
163 |
167 |
164 if(conn != null) conn.disconnect(); |
168 if(conn != null) conn.disconnect(); |
165 |
169 |
166 if(checkMD5(digester, pack))return 0l; |
170 if(checkMD5(digester, pack))return EXIT_SUCCESS; |
167 else return -1l; |
171 else return EXIT_MD5; |
168 } |
172 } |
169 |
173 |
170 //TODO proper result handling |
174 //TODO proper result handling |
171 protected void onPostExecute(Long result){ |
175 protected void onPostExecute(Integer result){ |
172 task.done(result > -1l); |
176 task.done(result); |
173 } |
177 } |
174 |
178 |
175 protected void onProgressUpdate(Object...objects){ |
179 protected void onProgressUpdate(Object...objects){ |
176 task.update((Integer)objects[0], (Integer)objects[1], (String)objects[2]); |
180 task.update((Integer)objects[0], (Integer)objects[1], (String)objects[2]); |
|
181 } |
|
182 |
|
183 protected void onCancelled(){ |
|
184 onPostExecute(EXIT_CANCELLED); |
177 } |
185 } |
178 |
186 |
179 private boolean checkMD5(MessageDigest digester, DownloadPackage task){ |
187 private boolean checkMD5(MessageDigest digester, DownloadPackage task){ |
180 if(digester != null) { |
188 if(digester != null) { |
181 byte[] messageDigest = digester.digest(); |
189 byte[] messageDigest = digester.digest(); |
195 tmp = 0xFF & messageDigest[i]; |
203 tmp = 0xFF & messageDigest[i]; |
196 if(tmp < 0xF) sb.append('0'); |
204 if(tmp < 0xF) sb.append('0'); |
197 sb.append(Integer.toHexString(tmp)); |
205 sb.append(Integer.toHexString(tmp)); |
198 } |
206 } |
199 sb.append('\n');//add newline to become identical with the hash file |
207 sb.append('\n');//add newline to become identical with the hash file |
200 |
208 |
201 return hash.equals(sb.toString()); |
209 return hash.equals(sb.toString()); |
202 } |
210 } |
203 return false; |
211 return false; |
204 } catch (IOException e) { |
212 } catch (IOException e) { |
205 e.printStackTrace(); |
213 e.printStackTrace(); |
206 return false; |
214 return true; |
207 } |
215 } |
208 }else{ |
216 }else{ |
209 return false; |
217 return true; |
210 } |
218 } |
211 |
219 |
212 } |
220 } |
213 |
221 |
214 } |
222 } |