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